#ifndef CPU_H
#define CPU_H

/* see main.c for definition */

int32 PCX; /* external view of PC                          */
int32 AF;  /* AF register                                  */
int32 BC;  /* BC register                                  */
int32 DE;  /* DE register                                  */
int32 HL;  /* HL register                                  */
int32 IX;  /* IX register                                  */
int32 IY;  /* IY register                                  */
int32 PC;  /* program counter                              */
int32 SP;  /* SP register                                  */
int32 AF1; /* alternate AF register                        */
int32 BC1; /* alternate BC register                        */
int32 DE1; /* alternate DE register                        */
int32 HL1; /* alternate HL register                        */
int32 IFF; /* Interrupt Flip Flop                          */
int32 IR;  /* Interrupt (upper) / Refresh (lower) register */
int32 Status = STATUS_RUNNING; /* Status of the CPU 0=running 1=end request 2=back to CCP */
int32 Debug = 0;
int32 Step = -1;

#ifdef iDEBUG
FILE* iLogFile;
char iLogBuffer[256];
const char* iLogTxt;
#endif

/* increase R by val (to correctly implement refresh counter) if enabled */
#ifdef DO_INCR
#define INCR(val) IR = (IR & ~0x3f) | ((IR + (val)) & 0x3f)
#else
#define INCR(val) ;
#endif

/*
	Functions needed by the soft CPU implementation
*/
void cpu_out(const uint32 p, const uint32 v) {
	if (p == 0xFF) {
		_Bios();
	} else {
		_HardwareOut(p, v);
	}
}

uint32 cpu_in(const uint32 p) {
	uint32 v;
	if (p == 0xFF) {
		_Bdos();
		v = HIGH_REGISTER(AF);
	} else {
		v = _HardwareIn(p);
	}
	return(v);
}

/* Z80 Custom soft core */

#define ADDRMASK        0xffff

#define FLAG_C  1
#define FLAG_N  2
#define FLAG_P  4
#define FLAG_H  16
#define FLAG_Z  64
#define FLAG_S  128

#define SETFLAG(f,c)    (AF = (c) ? AF | FLAG_ ## f : AF & ~FLAG_ ## f)
#define TSTFLAG(f)      ((AF & FLAG_ ## f) != 0)

#define SET_PVS(s)  (((cbits >> 6) ^ (cbits >> 5)) & 4)
#define SET_PV      (SET_PVS(sum))
#define SET_PV2(x)  ((temp == (x)) << 2)

#define POP(x)  {                               \
    uint32 y = RAM_PP(SP);                      \
    x = y + (RAM_PP(SP) << 8);                  \
}

#define JPC(cond) {                             \
    if (cond) {                                 \
        PC = GET_WORD(PC);                      \
    } else {                                    \
		PC++;                                   \
        PC++;                                   \
    }                                           \
}

#define CALLC(cond) {                           \
    if (cond) {                                 \
        uint32 a = GET_WORD(PC);                \
        PUSH(PC + 2);                           \
        PC = a;                                 \
    } else {                                    \
		PC++;                                   \
        PC++;                                   \
    }                                           \
}

/* the following tables precompute some common subexpressions
parityTable[i]          0..255  (number of 1's in i is odd) ? 0 : 4
incTable[i]             0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4)
decTable[i]             0..255  (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2
cbitsTable[i]           0..511  (i & 0x10) | ((i >> 8) & 1)
cbitsDup8Table[i]       0..511  (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6)
cbitsDup16Table[i]      0..511  (i & 0x10) | ((i >> 8) & 1) | (i & 0x28)
cbits2Table[i]          0..511  (i & 0x10) | ((i >> 8) & 1) | 2
rrcaTable[i]            0..255  ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
rraTable[i]             0..255  ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1)
addTable[i]             0..511  ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6)
subTable[i]             0..255  ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2
andTable[i]             0..255  (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i]
xororTable[i]           0..255  (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i]
rotateShiftTable[i]     0..255  (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff]
incZ80Table[i]          0..256! (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2)
decZ80Table[i]          0..255  (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2
cbitsZ80Table[i]        0..511  (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1)
cbitsZ80DupTable[i]     0..511  (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | (i & 0xa8)
cbits2Z80Table[i]       0..511  (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2
cbits2Z80DupTable[i]    0..511  (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 | (i & 0xa8)
negTable[i]             0..255  (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0)
rrdrldTable[i]          0..255  (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i]
cpTable[i]              0..255  (i & 0x80) | (((i & 0xff) == 0) << 6)
*/

#define preTables // Use precomputed tables (increases the size of the binary by about 4k)

/* parityTable[i] = (number of 1's in i is odd) ? 0 : 4, i = 0..255 */
#ifdef preTables
static const uint8 parityTable[256] = {
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	0,4,4,0,4,0,0,4,4,0,0,4,0,4,4,0,
	4,0,0,4,0,4,4,0,0,4,4,0,4,0,0,4,
};

/* incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4), i = 0..256 */
static const uint8 incTable[257] = {
	80,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80
};

/* decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2, i = 0..255 */
static const uint8 decTable[256] = {
	66,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
};

/* cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1), i = 0..511 */
static const uint8 cbitsTable[512] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
};

/* cbitsDup8Table[i] = (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */
static const uint16 cbitsDup8Table[512] = {
	0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
	0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
	0x1010,0x1110,0x1210,0x1310,0x1410,0x1510,0x1610,0x1710,
	0x1818,0x1918,0x1a18,0x1b18,0x1c18,0x1d18,0x1e18,0x1f18,
	0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
	0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
	0x3030,0x3130,0x3230,0x3330,0x3430,0x3530,0x3630,0x3730,
	0x3838,0x3938,0x3a38,0x3b38,0x3c38,0x3d38,0x3e38,0x3f38,
	0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
	0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
	0x5010,0x5110,0x5210,0x5310,0x5410,0x5510,0x5610,0x5710,
	0x5818,0x5918,0x5a18,0x5b18,0x5c18,0x5d18,0x5e18,0x5f18,
	0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
	0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
	0x7030,0x7130,0x7230,0x7330,0x7430,0x7530,0x7630,0x7730,
	0x7838,0x7938,0x7a38,0x7b38,0x7c38,0x7d38,0x7e38,0x7f38,
	0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
	0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
	0x9090,0x9190,0x9290,0x9390,0x9490,0x9590,0x9690,0x9790,
	0x9898,0x9998,0x9a98,0x9b98,0x9c98,0x9d98,0x9e98,0x9f98,
	0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
	0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
	0xb0b0,0xb1b0,0xb2b0,0xb3b0,0xb4b0,0xb5b0,0xb6b0,0xb7b0,
	0xb8b8,0xb9b8,0xbab8,0xbbb8,0xbcb8,0xbdb8,0xbeb8,0xbfb8,
	0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
	0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
	0xd090,0xd190,0xd290,0xd390,0xd490,0xd590,0xd690,0xd790,
	0xd898,0xd998,0xda98,0xdb98,0xdc98,0xdd98,0xde98,0xdf98,
	0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
	0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
	0xf0b0,0xf1b0,0xf2b0,0xf3b0,0xf4b0,0xf5b0,0xf6b0,0xf7b0,
	0xf8b8,0xf9b8,0xfab8,0xfbb8,0xfcb8,0xfdb8,0xfeb8,0xffb8,
	0x0041,0x0101,0x0201,0x0301,0x0401,0x0501,0x0601,0x0701,
	0x0809,0x0909,0x0a09,0x0b09,0x0c09,0x0d09,0x0e09,0x0f09,
	0x1011,0x1111,0x1211,0x1311,0x1411,0x1511,0x1611,0x1711,
	0x1819,0x1919,0x1a19,0x1b19,0x1c19,0x1d19,0x1e19,0x1f19,
	0x2021,0x2121,0x2221,0x2321,0x2421,0x2521,0x2621,0x2721,
	0x2829,0x2929,0x2a29,0x2b29,0x2c29,0x2d29,0x2e29,0x2f29,
	0x3031,0x3131,0x3231,0x3331,0x3431,0x3531,0x3631,0x3731,
	0x3839,0x3939,0x3a39,0x3b39,0x3c39,0x3d39,0x3e39,0x3f39,
	0x4001,0x4101,0x4201,0x4301,0x4401,0x4501,0x4601,0x4701,
	0x4809,0x4909,0x4a09,0x4b09,0x4c09,0x4d09,0x4e09,0x4f09,
	0x5011,0x5111,0x5211,0x5311,0x5411,0x5511,0x5611,0x5711,
	0x5819,0x5919,0x5a19,0x5b19,0x5c19,0x5d19,0x5e19,0x5f19,
	0x6021,0x6121,0x6221,0x6321,0x6421,0x6521,0x6621,0x6721,
	0x6829,0x6929,0x6a29,0x6b29,0x6c29,0x6d29,0x6e29,0x6f29,
	0x7031,0x7131,0x7231,0x7331,0x7431,0x7531,0x7631,0x7731,
	0x7839,0x7939,0x7a39,0x7b39,0x7c39,0x7d39,0x7e39,0x7f39,
	0x8081,0x8181,0x8281,0x8381,0x8481,0x8581,0x8681,0x8781,
	0x8889,0x8989,0x8a89,0x8b89,0x8c89,0x8d89,0x8e89,0x8f89,
	0x9091,0x9191,0x9291,0x9391,0x9491,0x9591,0x9691,0x9791,
	0x9899,0x9999,0x9a99,0x9b99,0x9c99,0x9d99,0x9e99,0x9f99,
	0xa0a1,0xa1a1,0xa2a1,0xa3a1,0xa4a1,0xa5a1,0xa6a1,0xa7a1,
	0xa8a9,0xa9a9,0xaaa9,0xaba9,0xaca9,0xada9,0xaea9,0xafa9,
	0xb0b1,0xb1b1,0xb2b1,0xb3b1,0xb4b1,0xb5b1,0xb6b1,0xb7b1,
	0xb8b9,0xb9b9,0xbab9,0xbbb9,0xbcb9,0xbdb9,0xbeb9,0xbfb9,
	0xc081,0xc181,0xc281,0xc381,0xc481,0xc581,0xc681,0xc781,
	0xc889,0xc989,0xca89,0xcb89,0xcc89,0xcd89,0xce89,0xcf89,
	0xd091,0xd191,0xd291,0xd391,0xd491,0xd591,0xd691,0xd791,
	0xd899,0xd999,0xda99,0xdb99,0xdc99,0xdd99,0xde99,0xdf99,
	0xe0a1,0xe1a1,0xe2a1,0xe3a1,0xe4a1,0xe5a1,0xe6a1,0xe7a1,
	0xe8a9,0xe9a9,0xeaa9,0xeba9,0xeca9,0xeda9,0xeea9,0xefa9,
	0xf0b1,0xf1b1,0xf2b1,0xf3b1,0xf4b1,0xf5b1,0xf6b1,0xf7b1,
	0xf8b9,0xf9b9,0xfab9,0xfbb9,0xfcb9,0xfdb9,0xfeb9,0xffb9,
};

/* cbitsDup16Table[i] = (i & 0x10) | ((i >> 8) & 1) | (i & 0x28), i = 0..511 */
static const uint8 cbitsDup16Table[512] = {
	0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
	16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
	32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
	48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
	0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
	16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
	32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
	48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
	0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
	16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
	32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
	48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
	0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
	16,16,16,16,16,16,16,16,24,24,24,24,24,24,24,24,
	32,32,32,32,32,32,32,32,40,40,40,40,40,40,40,40,
	48,48,48,48,48,48,48,48,56,56,56,56,56,56,56,56,
	1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
	17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
	33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
	49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
	1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
	17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
	33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
	49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
	1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
	17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
	33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
	49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
	1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9,
	17,17,17,17,17,17,17,17,25,25,25,25,25,25,25,25,
	33,33,33,33,33,33,33,33,41,41,41,41,41,41,41,41,
	49,49,49,49,49,49,49,49,57,57,57,57,57,57,57,57,
};

/* cbits2Table[i] = (i & 0x10) | ((i >> 8) & 1) | 2, i = 0..511 */
static const uint8 cbits2Table[512] = {
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
};

/* rrcaTable[i] = ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
static const uint16 rrcaTable[256] = {
	0x0000,0x8001,0x0100,0x8101,0x0200,0x8201,0x0300,0x8301,
	0x0400,0x8401,0x0500,0x8501,0x0600,0x8601,0x0700,0x8701,
	0x0808,0x8809,0x0908,0x8909,0x0a08,0x8a09,0x0b08,0x8b09,
	0x0c08,0x8c09,0x0d08,0x8d09,0x0e08,0x8e09,0x0f08,0x8f09,
	0x1000,0x9001,0x1100,0x9101,0x1200,0x9201,0x1300,0x9301,
	0x1400,0x9401,0x1500,0x9501,0x1600,0x9601,0x1700,0x9701,
	0x1808,0x9809,0x1908,0x9909,0x1a08,0x9a09,0x1b08,0x9b09,
	0x1c08,0x9c09,0x1d08,0x9d09,0x1e08,0x9e09,0x1f08,0x9f09,
	0x2020,0xa021,0x2120,0xa121,0x2220,0xa221,0x2320,0xa321,
	0x2420,0xa421,0x2520,0xa521,0x2620,0xa621,0x2720,0xa721,
	0x2828,0xa829,0x2928,0xa929,0x2a28,0xaa29,0x2b28,0xab29,
	0x2c28,0xac29,0x2d28,0xad29,0x2e28,0xae29,0x2f28,0xaf29,
	0x3020,0xb021,0x3120,0xb121,0x3220,0xb221,0x3320,0xb321,
	0x3420,0xb421,0x3520,0xb521,0x3620,0xb621,0x3720,0xb721,
	0x3828,0xb829,0x3928,0xb929,0x3a28,0xba29,0x3b28,0xbb29,
	0x3c28,0xbc29,0x3d28,0xbd29,0x3e28,0xbe29,0x3f28,0xbf29,
	0x4000,0xc001,0x4100,0xc101,0x4200,0xc201,0x4300,0xc301,
	0x4400,0xc401,0x4500,0xc501,0x4600,0xc601,0x4700,0xc701,
	0x4808,0xc809,0x4908,0xc909,0x4a08,0xca09,0x4b08,0xcb09,
	0x4c08,0xcc09,0x4d08,0xcd09,0x4e08,0xce09,0x4f08,0xcf09,
	0x5000,0xd001,0x5100,0xd101,0x5200,0xd201,0x5300,0xd301,
	0x5400,0xd401,0x5500,0xd501,0x5600,0xd601,0x5700,0xd701,
	0x5808,0xd809,0x5908,0xd909,0x5a08,0xda09,0x5b08,0xdb09,
	0x5c08,0xdc09,0x5d08,0xdd09,0x5e08,0xde09,0x5f08,0xdf09,
	0x6020,0xe021,0x6120,0xe121,0x6220,0xe221,0x6320,0xe321,
	0x6420,0xe421,0x6520,0xe521,0x6620,0xe621,0x6720,0xe721,
	0x6828,0xe829,0x6928,0xe929,0x6a28,0xea29,0x6b28,0xeb29,
	0x6c28,0xec29,0x6d28,0xed29,0x6e28,0xee29,0x6f28,0xef29,
	0x7020,0xf021,0x7120,0xf121,0x7220,0xf221,0x7320,0xf321,
	0x7420,0xf421,0x7520,0xf521,0x7620,0xf621,0x7720,0xf721,
	0x7828,0xf829,0x7928,0xf929,0x7a28,0xfa29,0x7b28,0xfb29,
	0x7c28,0xfc29,0x7d28,0xfd29,0x7e28,0xfe29,0x7f28,0xff29,
};

/* rraTable[i] = ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1), i = 0..255 */
static const uint16 rraTable[256] = {
	0x0000,0x0001,0x0100,0x0101,0x0200,0x0201,0x0300,0x0301,
	0x0400,0x0401,0x0500,0x0501,0x0600,0x0601,0x0700,0x0701,
	0x0808,0x0809,0x0908,0x0909,0x0a08,0x0a09,0x0b08,0x0b09,
	0x0c08,0x0c09,0x0d08,0x0d09,0x0e08,0x0e09,0x0f08,0x0f09,
	0x1000,0x1001,0x1100,0x1101,0x1200,0x1201,0x1300,0x1301,
	0x1400,0x1401,0x1500,0x1501,0x1600,0x1601,0x1700,0x1701,
	0x1808,0x1809,0x1908,0x1909,0x1a08,0x1a09,0x1b08,0x1b09,
	0x1c08,0x1c09,0x1d08,0x1d09,0x1e08,0x1e09,0x1f08,0x1f09,
	0x2020,0x2021,0x2120,0x2121,0x2220,0x2221,0x2320,0x2321,
	0x2420,0x2421,0x2520,0x2521,0x2620,0x2621,0x2720,0x2721,
	0x2828,0x2829,0x2928,0x2929,0x2a28,0x2a29,0x2b28,0x2b29,
	0x2c28,0x2c29,0x2d28,0x2d29,0x2e28,0x2e29,0x2f28,0x2f29,
	0x3020,0x3021,0x3120,0x3121,0x3220,0x3221,0x3320,0x3321,
	0x3420,0x3421,0x3520,0x3521,0x3620,0x3621,0x3720,0x3721,
	0x3828,0x3829,0x3928,0x3929,0x3a28,0x3a29,0x3b28,0x3b29,
	0x3c28,0x3c29,0x3d28,0x3d29,0x3e28,0x3e29,0x3f28,0x3f29,
	0x4000,0x4001,0x4100,0x4101,0x4200,0x4201,0x4300,0x4301,
	0x4400,0x4401,0x4500,0x4501,0x4600,0x4601,0x4700,0x4701,
	0x4808,0x4809,0x4908,0x4909,0x4a08,0x4a09,0x4b08,0x4b09,
	0x4c08,0x4c09,0x4d08,0x4d09,0x4e08,0x4e09,0x4f08,0x4f09,
	0x5000,0x5001,0x5100,0x5101,0x5200,0x5201,0x5300,0x5301,
	0x5400,0x5401,0x5500,0x5501,0x5600,0x5601,0x5700,0x5701,
	0x5808,0x5809,0x5908,0x5909,0x5a08,0x5a09,0x5b08,0x5b09,
	0x5c08,0x5c09,0x5d08,0x5d09,0x5e08,0x5e09,0x5f08,0x5f09,
	0x6020,0x6021,0x6120,0x6121,0x6220,0x6221,0x6320,0x6321,
	0x6420,0x6421,0x6520,0x6521,0x6620,0x6621,0x6720,0x6721,
	0x6828,0x6829,0x6928,0x6929,0x6a28,0x6a29,0x6b28,0x6b29,
	0x6c28,0x6c29,0x6d28,0x6d29,0x6e28,0x6e29,0x6f28,0x6f29,
	0x7020,0x7021,0x7120,0x7121,0x7220,0x7221,0x7320,0x7321,
	0x7420,0x7421,0x7520,0x7521,0x7620,0x7621,0x7720,0x7721,
	0x7828,0x7829,0x7928,0x7929,0x7a28,0x7a29,0x7b28,0x7b29,
	0x7c28,0x7c29,0x7d28,0x7d29,0x7e28,0x7e29,0x7f28,0x7f29,
};

/* addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6), i = 0..511 */
static const uint16 addTable[512] = {
	0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
	0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
	0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
	0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
	0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
	0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
	0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
	0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
	0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
	0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
	0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
	0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
	0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
	0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
	0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
	0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
	0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
	0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
	0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
	0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
	0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
	0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
	0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
	0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
	0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
	0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
	0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
	0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
	0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
	0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
	0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
	0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
	0x0040,0x0100,0x0200,0x0300,0x0400,0x0500,0x0600,0x0700,
	0x0808,0x0908,0x0a08,0x0b08,0x0c08,0x0d08,0x0e08,0x0f08,
	0x1000,0x1100,0x1200,0x1300,0x1400,0x1500,0x1600,0x1700,
	0x1808,0x1908,0x1a08,0x1b08,0x1c08,0x1d08,0x1e08,0x1f08,
	0x2020,0x2120,0x2220,0x2320,0x2420,0x2520,0x2620,0x2720,
	0x2828,0x2928,0x2a28,0x2b28,0x2c28,0x2d28,0x2e28,0x2f28,
	0x3020,0x3120,0x3220,0x3320,0x3420,0x3520,0x3620,0x3720,
	0x3828,0x3928,0x3a28,0x3b28,0x3c28,0x3d28,0x3e28,0x3f28,
	0x4000,0x4100,0x4200,0x4300,0x4400,0x4500,0x4600,0x4700,
	0x4808,0x4908,0x4a08,0x4b08,0x4c08,0x4d08,0x4e08,0x4f08,
	0x5000,0x5100,0x5200,0x5300,0x5400,0x5500,0x5600,0x5700,
	0x5808,0x5908,0x5a08,0x5b08,0x5c08,0x5d08,0x5e08,0x5f08,
	0x6020,0x6120,0x6220,0x6320,0x6420,0x6520,0x6620,0x6720,
	0x6828,0x6928,0x6a28,0x6b28,0x6c28,0x6d28,0x6e28,0x6f28,
	0x7020,0x7120,0x7220,0x7320,0x7420,0x7520,0x7620,0x7720,
	0x7828,0x7928,0x7a28,0x7b28,0x7c28,0x7d28,0x7e28,0x7f28,
	0x8080,0x8180,0x8280,0x8380,0x8480,0x8580,0x8680,0x8780,
	0x8888,0x8988,0x8a88,0x8b88,0x8c88,0x8d88,0x8e88,0x8f88,
	0x9080,0x9180,0x9280,0x9380,0x9480,0x9580,0x9680,0x9780,
	0x9888,0x9988,0x9a88,0x9b88,0x9c88,0x9d88,0x9e88,0x9f88,
	0xa0a0,0xa1a0,0xa2a0,0xa3a0,0xa4a0,0xa5a0,0xa6a0,0xa7a0,
	0xa8a8,0xa9a8,0xaaa8,0xaba8,0xaca8,0xada8,0xaea8,0xafa8,
	0xb0a0,0xb1a0,0xb2a0,0xb3a0,0xb4a0,0xb5a0,0xb6a0,0xb7a0,
	0xb8a8,0xb9a8,0xbaa8,0xbba8,0xbca8,0xbda8,0xbea8,0xbfa8,
	0xc080,0xc180,0xc280,0xc380,0xc480,0xc580,0xc680,0xc780,
	0xc888,0xc988,0xca88,0xcb88,0xcc88,0xcd88,0xce88,0xcf88,
	0xd080,0xd180,0xd280,0xd380,0xd480,0xd580,0xd680,0xd780,
	0xd888,0xd988,0xda88,0xdb88,0xdc88,0xdd88,0xde88,0xdf88,
	0xe0a0,0xe1a0,0xe2a0,0xe3a0,0xe4a0,0xe5a0,0xe6a0,0xe7a0,
	0xe8a8,0xe9a8,0xeaa8,0xeba8,0xeca8,0xeda8,0xeea8,0xefa8,
	0xf0a0,0xf1a0,0xf2a0,0xf3a0,0xf4a0,0xf5a0,0xf6a0,0xf7a0,
	0xf8a8,0xf9a8,0xfaa8,0xfba8,0xfca8,0xfda8,0xfea8,0xffa8,
};

/* subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2, i = 0..255 */
static const uint16 subTable[256] = {
	0x0042,0x0102,0x0202,0x0302,0x0402,0x0502,0x0602,0x0702,
	0x080a,0x090a,0x0a0a,0x0b0a,0x0c0a,0x0d0a,0x0e0a,0x0f0a,
	0x1002,0x1102,0x1202,0x1302,0x1402,0x1502,0x1602,0x1702,
	0x180a,0x190a,0x1a0a,0x1b0a,0x1c0a,0x1d0a,0x1e0a,0x1f0a,
	0x2022,0x2122,0x2222,0x2322,0x2422,0x2522,0x2622,0x2722,
	0x282a,0x292a,0x2a2a,0x2b2a,0x2c2a,0x2d2a,0x2e2a,0x2f2a,
	0x3022,0x3122,0x3222,0x3322,0x3422,0x3522,0x3622,0x3722,
	0x382a,0x392a,0x3a2a,0x3b2a,0x3c2a,0x3d2a,0x3e2a,0x3f2a,
	0x4002,0x4102,0x4202,0x4302,0x4402,0x4502,0x4602,0x4702,
	0x480a,0x490a,0x4a0a,0x4b0a,0x4c0a,0x4d0a,0x4e0a,0x4f0a,
	0x5002,0x5102,0x5202,0x5302,0x5402,0x5502,0x5602,0x5702,
	0x580a,0x590a,0x5a0a,0x5b0a,0x5c0a,0x5d0a,0x5e0a,0x5f0a,
	0x6022,0x6122,0x6222,0x6322,0x6422,0x6522,0x6622,0x6722,
	0x682a,0x692a,0x6a2a,0x6b2a,0x6c2a,0x6d2a,0x6e2a,0x6f2a,
	0x7022,0x7122,0x7222,0x7322,0x7422,0x7522,0x7622,0x7722,
	0x782a,0x792a,0x7a2a,0x7b2a,0x7c2a,0x7d2a,0x7e2a,0x7f2a,
	0x8082,0x8182,0x8282,0x8382,0x8482,0x8582,0x8682,0x8782,
	0x888a,0x898a,0x8a8a,0x8b8a,0x8c8a,0x8d8a,0x8e8a,0x8f8a,
	0x9082,0x9182,0x9282,0x9382,0x9482,0x9582,0x9682,0x9782,
	0x988a,0x998a,0x9a8a,0x9b8a,0x9c8a,0x9d8a,0x9e8a,0x9f8a,
	0xa0a2,0xa1a2,0xa2a2,0xa3a2,0xa4a2,0xa5a2,0xa6a2,0xa7a2,
	0xa8aa,0xa9aa,0xaaaa,0xabaa,0xacaa,0xadaa,0xaeaa,0xafaa,
	0xb0a2,0xb1a2,0xb2a2,0xb3a2,0xb4a2,0xb5a2,0xb6a2,0xb7a2,
	0xb8aa,0xb9aa,0xbaaa,0xbbaa,0xbcaa,0xbdaa,0xbeaa,0xbfaa,
	0xc082,0xc182,0xc282,0xc382,0xc482,0xc582,0xc682,0xc782,
	0xc88a,0xc98a,0xca8a,0xcb8a,0xcc8a,0xcd8a,0xce8a,0xcf8a,
	0xd082,0xd182,0xd282,0xd382,0xd482,0xd582,0xd682,0xd782,
	0xd88a,0xd98a,0xda8a,0xdb8a,0xdc8a,0xdd8a,0xde8a,0xdf8a,
	0xe0a2,0xe1a2,0xe2a2,0xe3a2,0xe4a2,0xe5a2,0xe6a2,0xe7a2,
	0xe8aa,0xe9aa,0xeaaa,0xebaa,0xecaa,0xedaa,0xeeaa,0xefaa,
	0xf0a2,0xf1a2,0xf2a2,0xf3a2,0xf4a2,0xf5a2,0xf6a2,0xf7a2,
	0xf8aa,0xf9aa,0xfaaa,0xfbaa,0xfcaa,0xfdaa,0xfeaa,0xffaa,
};

/* andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i], i = 0..255 */
static const uint16 andTable[256] = {
	0x0054,0x0110,0x0210,0x0314,0x0410,0x0514,0x0614,0x0710,
	0x0818,0x091c,0x0a1c,0x0b18,0x0c1c,0x0d18,0x0e18,0x0f1c,
	0x1010,0x1114,0x1214,0x1310,0x1414,0x1510,0x1610,0x1714,
	0x181c,0x1918,0x1a18,0x1b1c,0x1c18,0x1d1c,0x1e1c,0x1f18,
	0x2030,0x2134,0x2234,0x2330,0x2434,0x2530,0x2630,0x2734,
	0x283c,0x2938,0x2a38,0x2b3c,0x2c38,0x2d3c,0x2e3c,0x2f38,
	0x3034,0x3130,0x3230,0x3334,0x3430,0x3534,0x3634,0x3730,
	0x3838,0x393c,0x3a3c,0x3b38,0x3c3c,0x3d38,0x3e38,0x3f3c,
	0x4010,0x4114,0x4214,0x4310,0x4414,0x4510,0x4610,0x4714,
	0x481c,0x4918,0x4a18,0x4b1c,0x4c18,0x4d1c,0x4e1c,0x4f18,
	0x5014,0x5110,0x5210,0x5314,0x5410,0x5514,0x5614,0x5710,
	0x5818,0x591c,0x5a1c,0x5b18,0x5c1c,0x5d18,0x5e18,0x5f1c,
	0x6034,0x6130,0x6230,0x6334,0x6430,0x6534,0x6634,0x6730,
	0x6838,0x693c,0x6a3c,0x6b38,0x6c3c,0x6d38,0x6e38,0x6f3c,
	0x7030,0x7134,0x7234,0x7330,0x7434,0x7530,0x7630,0x7734,
	0x783c,0x7938,0x7a38,0x7b3c,0x7c38,0x7d3c,0x7e3c,0x7f38,
	0x8090,0x8194,0x8294,0x8390,0x8494,0x8590,0x8690,0x8794,
	0x889c,0x8998,0x8a98,0x8b9c,0x8c98,0x8d9c,0x8e9c,0x8f98,
	0x9094,0x9190,0x9290,0x9394,0x9490,0x9594,0x9694,0x9790,
	0x9898,0x999c,0x9a9c,0x9b98,0x9c9c,0x9d98,0x9e98,0x9f9c,
	0xa0b4,0xa1b0,0xa2b0,0xa3b4,0xa4b0,0xa5b4,0xa6b4,0xa7b0,
	0xa8b8,0xa9bc,0xaabc,0xabb8,0xacbc,0xadb8,0xaeb8,0xafbc,
	0xb0b0,0xb1b4,0xb2b4,0xb3b0,0xb4b4,0xb5b0,0xb6b0,0xb7b4,
	0xb8bc,0xb9b8,0xbab8,0xbbbc,0xbcb8,0xbdbc,0xbebc,0xbfb8,
	0xc094,0xc190,0xc290,0xc394,0xc490,0xc594,0xc694,0xc790,
	0xc898,0xc99c,0xca9c,0xcb98,0xcc9c,0xcd98,0xce98,0xcf9c,
	0xd090,0xd194,0xd294,0xd390,0xd494,0xd590,0xd690,0xd794,
	0xd89c,0xd998,0xda98,0xdb9c,0xdc98,0xdd9c,0xde9c,0xdf98,
	0xe0b0,0xe1b4,0xe2b4,0xe3b0,0xe4b4,0xe5b0,0xe6b0,0xe7b4,
	0xe8bc,0xe9b8,0xeab8,0xebbc,0xecb8,0xedbc,0xeebc,0xefb8,
	0xf0b4,0xf1b0,0xf2b0,0xf3b4,0xf4b0,0xf5b4,0xf6b4,0xf7b0,
	0xf8b8,0xf9bc,0xfabc,0xfbb8,0xfcbc,0xfdb8,0xfeb8,0xffbc,
};

/* xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i], i = 0..255 */
static const uint16 xororTable[256] = {
	0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
	0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
	0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
	0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
	0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
	0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
	0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
	0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
	0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
	0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
	0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
	0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
	0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
	0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
	0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
	0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
	0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
	0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
	0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
	0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
	0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
	0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
	0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
	0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
	0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
	0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
	0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
	0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
	0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
	0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
	0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
	0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
};

/* rotateShiftTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff], i = 0..255 */
static const uint8 rotateShiftTable[256] = {
	68,  0,  0,  4,  0,  4,  4,  0,  8, 12, 12,  8, 12,  8,  8, 12,
	0,  4,  4,  0,  4,  0,  0,  4, 12,  8,  8, 12,  8, 12, 12,  8,
	32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
	36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
	0,  4,  4,  0,  4,  0,  0,  4, 12,  8,  8, 12,  8, 12, 12,  8,
	4,  0,  0,  4,  0,  4,  4,  0,  8, 12, 12,  8, 12,  8,  8, 12,
	36, 32, 32, 36, 32, 36, 36, 32, 40, 44, 44, 40, 44, 40, 40, 44,
	32, 36, 36, 32, 36, 32, 32, 36, 44, 40, 40, 44, 40, 44, 44, 40,
	128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
	132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
	164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
	160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
	132,128,128,132,128,132,132,128,136,140,140,136,140,136,136,140,
	128,132,132,128,132,128,128,132,140,136,136,140,136,140,140,136,
	160,164,164,160,164,160,160,164,172,168,168,172,168,172,172,168,
	164,160,160,164,160,164,164,160,168,172,172,168,172,168,168,172,
};

/* incZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2), i = 0..256 */
static const uint8 incZ80Table[257] = {
	80,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	148,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	144,128,128,128,128,128,128,128,136,136,136,136,136,136,136,136,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168,
	176,160,160,160,160,160,160,160,168,168,168,168,168,168,168,168, 80,
};

/* decZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2, i = 0..255 */
static const uint8 decZ80Table[256] = {
	66,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 58,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 62,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	130,130,130,130,130,130,130,130,138,138,138,138,138,138,138,154,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
	162,162,162,162,162,162,162,162,170,170,170,170,170,170,170,186,
};

/* cbitsZ80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1), i = 0..511 */
static const uint8 cbitsZ80Table[512] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
	4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
	20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
	21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
	21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
	21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
	21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
};

/* cbitsZ80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | (i & 0xa8), i = 0..511 */
static const uint8 cbitsZ80DupTable[512] = {
	0,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
	32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
	0,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,  8,  8,  8,  8,
	16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24,
	32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40,
	48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56,
	132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
	148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
	164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
	180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
	132,132,132,132,132,132,132,132,140,140,140,140,140,140,140,140,
	148,148,148,148,148,148,148,148,156,156,156,156,156,156,156,156,
	164,164,164,164,164,164,164,164,172,172,172,172,172,172,172,172,
	180,180,180,180,180,180,180,180,188,188,188,188,188,188,188,188,
	5,  5,  5,  5,  5,  5,  5,  5, 13, 13, 13, 13, 13, 13, 13, 13,
	21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
	37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
	53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
	5,  5,  5,  5,  5,  5,  5,  5, 13, 13, 13, 13, 13, 13, 13, 13,
	21, 21, 21, 21, 21, 21, 21, 21, 29, 29, 29, 29, 29, 29, 29, 29,
	37, 37, 37, 37, 37, 37, 37, 37, 45, 45, 45, 45, 45, 45, 45, 45,
	53, 53, 53, 53, 53, 53, 53, 53, 61, 61, 61, 61, 61, 61, 61, 61,
	129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
	145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
	161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
	177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
	129,129,129,129,129,129,129,129,137,137,137,137,137,137,137,137,
	145,145,145,145,145,145,145,145,153,153,153,153,153,153,153,153,
	161,161,161,161,161,161,161,161,169,169,169,169,169,169,169,169,
	177,177,177,177,177,177,177,177,185,185,185,185,185,185,185,185,
};

/* cbits2Z80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2, i = 0..511 */
static const uint8 cbits2Z80Table[512] = {
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
	22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
	22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
	22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
	22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
};

/* cbits2Z80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 | (i & 0xa8), i = 0..511 */
static const uint8 cbits2Z80DupTable[512] = {
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 10,
	18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
	50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
	2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10, 10,
	18, 18, 18, 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26,
	34, 34, 34, 34, 34, 34, 34, 34, 42, 42, 42, 42, 42, 42, 42, 42,
	50, 50, 50, 50, 50, 50, 50, 50, 58, 58, 58, 58, 58, 58, 58, 58,
	134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
	150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
	166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
	182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
	134,134,134,134,134,134,134,134,142,142,142,142,142,142,142,142,
	150,150,150,150,150,150,150,150,158,158,158,158,158,158,158,158,
	166,166,166,166,166,166,166,166,174,174,174,174,174,174,174,174,
	182,182,182,182,182,182,182,182,190,190,190,190,190,190,190,190,
	7,  7,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15, 15, 15,
	23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
	39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
	55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
	7,  7,  7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15, 15, 15,
	23, 23, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31,
	39, 39, 39, 39, 39, 39, 39, 39, 47, 47, 47, 47, 47, 47, 47, 47,
	55, 55, 55, 55, 55, 55, 55, 55, 63, 63, 63, 63, 63, 63, 63, 63,
	131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
	147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
	163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
	179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
	131,131,131,131,131,131,131,131,139,139,139,139,139,139,139,139,
	147,147,147,147,147,147,147,147,155,155,155,155,155,155,155,155,
	163,163,163,163,163,163,163,163,171,171,171,171,171,171,171,171,
	179,179,179,179,179,179,179,179,187,187,187,187,187,187,187,187,
};

/* negTable[i] = (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0), i = 0..255 */
static const uint8 negTable[256] = {
	2,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	7,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
	3,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
};

/* rrdrldTable[i] = (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i], i = 0..255 */
static const uint16 rrdrldTable[256] = {
	0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,
	0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,
	0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,
	0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,
	0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,
	0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,
	0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,
	0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,
	0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,
	0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,
	0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,
	0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,
	0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,
	0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,
	0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,
	0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,
	0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,
	0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,
	0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,
	0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,
	0xa0a4,0xa1a0,0xa2a0,0xa3a4,0xa4a0,0xa5a4,0xa6a4,0xa7a0,
	0xa8a8,0xa9ac,0xaaac,0xaba8,0xacac,0xada8,0xaea8,0xafac,
	0xb0a0,0xb1a4,0xb2a4,0xb3a0,0xb4a4,0xb5a0,0xb6a0,0xb7a4,
	0xb8ac,0xb9a8,0xbaa8,0xbbac,0xbca8,0xbdac,0xbeac,0xbfa8,
	0xc084,0xc180,0xc280,0xc384,0xc480,0xc584,0xc684,0xc780,
	0xc888,0xc98c,0xca8c,0xcb88,0xcc8c,0xcd88,0xce88,0xcf8c,
	0xd080,0xd184,0xd284,0xd380,0xd484,0xd580,0xd680,0xd784,
	0xd88c,0xd988,0xda88,0xdb8c,0xdc88,0xdd8c,0xde8c,0xdf88,
	0xe0a0,0xe1a4,0xe2a4,0xe3a0,0xe4a4,0xe5a0,0xe6a0,0xe7a4,
	0xe8ac,0xe9a8,0xeaa8,0xebac,0xeca8,0xedac,0xeeac,0xefa8,
	0xf0a4,0xf1a0,0xf2a0,0xf3a4,0xf4a0,0xf5a4,0xf6a4,0xf7a0,
	0xf8a8,0xf9ac,0xfaac,0xfba8,0xfcac,0xfda8,0xfea8,0xffac,
};

/* cpTable[i] = (i & 0x80) | (((i & 0xff) == 0) << 6), i = 0..255 */
static const uint8 cpTable[256] = {
	64,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
	128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
};
#endif

#ifndef preTables
static uint8 parityTable[256];
static uint8 incTable[257];
static uint8 decTable[256];
static uint8 cbitsTable[512];
static uint16 cbitsDup8Table[512];
static uint8 cbitsDup16Table[512];
static uint8 cbits2Table[512];
static uint16 rrcaTable[256];
static uint16 rraTable[256];
static uint16 addTable[512];
static uint16 subTable[256];
static uint16 andTable[256];
static uint16 xororTable[256];
static uint8 rotateShiftTable[256];
static uint8 incZ80Table[257];
static uint8 decZ80Table[256];
static uint8 cbitsZ80Table[512];
static uint8 cbitsZ80DupTable[512];
static uint8 cbits2Z80Table[512];
static uint8 cbits2Z80DupTable[512];
static uint8 negTable[256];
static uint16 rrdrldTable[256];
static uint8 cpTable[256];

void initTables(void) {
	// 256 bytes tables
	for (int i = 0; i < 256; i++) {
		char c = 0;
		for (int j = 0; j < 8; j++) {
			if (i & (1 << j))
				c++;
		}
		parityTable[i] = (c & 1) ? 0 : 4;
		decTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | 2;
		rrcaTable[i] = ((i & 1) << 15) | ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1);
		rraTable[i] = ((i >> 1) << 8) | ((i >> 1) & 0x28) | (i & 1);
		subTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | 2;
		andTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | 0x10 | parityTable[i];
		xororTable[i] = (i << 8) | (i & 0xa8) | ((i == 0) << 6) | parityTable[i];
		rotateShiftTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i & 0xff];
		decZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0xf) << 4) | ((i == 0x7f) << 2) | 2;
		negTable[i] = (((i & 0x0f) != 0) << 4) | ((i == 0x80) << 2) | 2 | (i != 0);
		rrdrldTable[i] = (i << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6) | parityTable[i];
		cpTable[i] = (i & 0x80) | (((i & 0xff) == 0) << 6);
	}
	// 257 bytes tables
	for (int i = 0; i < 257; i++) {
		incTable[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4);
		incZ80Table[i] = (i & 0xa8) | (((i & 0xff) == 0) << 6) | (((i & 0xf) == 0) << 4) | ((i == 0x80) << 2);
	}
	// 512 bytes tables
	for (int i = 0; i < 512; i++) {
		cbitsTable[i] = (i & 0x10) | ((i >> 8) & 1);
		cbitsDup8Table[i] = (i & 0x10) | ((i >> 8) & 1) | ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6);
		cbitsDup16Table[i] = (i & 0x10) | ((i >> 8) & 1) | (i & 0x28);
		cbits2Table[i] = (i & 0x10) | ((i >> 8) & 1) | 2;
		addTable[i] = ((i & 0xff) << 8) | (i & 0xa8) | (((i & 0xff) == 0) << 6);
		cbitsZ80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1);
		cbitsZ80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | (i & 0xa8);
		cbits2Z80Table[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2;
		cbits2Z80DupTable[i] = (i & 0x10) | (((i >> 6) ^ (i >> 5)) & 4) | ((i >> 8) & 1) | 2 | (i & 0xa8);
	}
}
#endif

#if defined(DEBUG) || defined(iDEBUG)
static const char* Mnemonics[256] =
{
	"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA",
	"EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA",
	"DJNZ @h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA",
	"JR @h", "ADD HL,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA",
	"JR NZ,@h", "LD HL,#h", "LD (#h),HL", "INC HL", "INC H", "DEC H", "LD H,*h", "DAA",
	"JR Z,@h", "ADD HL,HL", "LD HL,(#h)", "DEC HL", "INC L", "DEC L", "LD L,*h", "CPL",
	"JR NC,@h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (HL)", "DEC (HL)", "LD (HL),*h", "SCF",
	"JR C,@h", "ADD HL,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF",
	"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,H", "LD B,L", "LD B,(HL)", "LD B,A",
	"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,H", "LD C,L", "LD C,(HL)", "LD C,A",
	"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,H", "LD D,L", "LD D,(HL)", "LD D,A",
	"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,H", "LD E,L", "LD E,(HL)", "LD E,A",
	"LD H,B", "LD H,C", "LD H,D", "LD H,E", "LD H,H", "LD H,L", "LD H,(HL)", "LD H,A",
	"LD L,B", "LD L,C", "LD L,D", "LD L,E", "LD L,H", "LD L,L", "LD L,(HL)", "LD L,A",
	"LD (HL),B", "LD (HL),C", "LD (HL),D", "LD (HL),E", "LD (HL),H", "LD (HL),L", "HALT", "LD (HL),A",
	"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,H", "LD A,L", "LD A,(HL)", "LD A,A",
	"ADD B", "ADD C", "ADD D", "ADD E", "ADD H", "ADD L", "ADD (HL)", "ADD A",
	"ADC B", "ADC C", "ADC D", "ADC E", "ADC H", "ADC L", "ADC (HL)", "ADC A",
	"SUB B", "SUB C", "SUB D", "SUB E", "SUB H", "SUB L", "SUB (HL)", "SUB A",
	"SBC B", "SBC C", "SBC D", "SBC E", "SBC H", "SBC L", "SBC (HL)", "SBC A",
	"AND B", "AND C", "AND D", "AND E", "AND H", "AND L", "AND (HL)", "AND A",
	"XOR B", "XOR C", "XOR D", "XOR E", "XOR H", "XOR L", "XOR (HL)", "XOR A",
	"OR B", "OR C", "OR D", "OR E", "OR H", "OR L", "OR (HL)", "OR A",
	"CP B", "CP C", "CP D", "CP E", "CP H", "CP L", "CP (HL)", "CP A",
	"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD *h", "RST 00h",
	"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC *h", "RST 08h",
	"RET NC", "POP DE", "JP NC,#h", "OUTA (*h)", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h",
	"RET C", "EXX", "JP C,#h", "INA (*h)", "CALL C,#h", "PFX_DD", "SBC *h", "RST 18h",
	"RET PO", "POP HL", "JP PO,#h", "EX HL,(SP)", "CALL PO,#h", "PUSH HL", "AND *h", "RST 20h",
	"RET PE", "LD PC,HL", "JP PE,#h", "EX DE,HL", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h",
	"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h",
	"RET M", "LD SP,HL", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h"
};

static const char* MnemonicsCB[256] =
{
	"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (HL)", "RLC A",
	"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (HL)", "RRC A",
	"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (HL)", "RL A",
	"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (HL)", "RR A",
	"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (HL)", "SLA A",
	"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (HL)", "SRA A",
	"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (HL)", "SLL A",
	"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (HL)", "SRL A",
	"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(HL)", "BIT 0,A",
	"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(HL)", "BIT 1,A",
	"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(HL)", "BIT 2,A",
	"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(HL)", "BIT 3,A",
	"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(HL)", "BIT 4,A",
	"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(HL)", "BIT 5,A",
	"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(HL)", "BIT 6,A",
	"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(HL)", "BIT 7,A",
	"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(HL)", "RES 0,A",
	"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(HL)", "RES 1,A",
	"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(HL)", "RES 2,A",
	"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(HL)", "RES 3,A",
	"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(HL)", "RES 4,A",
	"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(HL)", "RES 5,A",
	"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(HL)", "RES 6,A",
	"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(HL)", "RES 7,A",
	"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(HL)", "SET 0,A",
	"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(HL)", "SET 1,A",
	"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(HL)", "SET 2,A",
	"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(HL)", "SET 3,A",
	"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(HL)", "SET 4,A",
	"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(HL)", "SET 5,A",
	"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(HL)", "SET 6,A",
	"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(HL)", "SET 7,A"
};

static const char* MnemonicsED[256] =
{
	"DB EDh,00h", "DB EDh,01h", "DB EDh,02h", "DB EDh,03h",
	"DB EDh,04h", "DB EDh,05h", "DB EDh,06h", "DB EDh,07h",
	"DB EDh,08h", "DB EDh,09h", "DB EDh,0Ah", "DB EDh,0Bh",
	"DB EDh,0Ch", "DB EDh,0Dh", "DB EDh,0Eh", "DB EDh,0Fh",
	"DB EDh,10h", "DB EDh,11h", "DB EDh,12h", "DB EDh,13h",
	"DB EDh,14h", "DB EDh,15h", "DB EDh,16h", "DB EDh,17h",
	"DB EDh,18h", "DB EDh,19h", "DB EDh,1Ah", "DB EDh,1Bh",
	"DB EDh,1Ch", "DB EDh,1Dh", "DB EDh,1Eh", "DB EDh,1Fh",
	"DB EDh,20h", "DB EDh,21h", "DB EDh,22h", "DB EDh,23h",
	"DB EDh,24h", "DB EDh,25h", "DB EDh,26h", "DB EDh,27h",
	"DB EDh,28h", "DB EDh,29h", "DB EDh,2Ah", "DB EDh,2Bh",
	"DB EDh,2Ch", "DB EDh,2Dh", "DB EDh,2Eh", "DB EDh,2Fh",
	"DB EDh,30h", "DB EDh,31h", "DB EDh,32h", "DB EDh,33h",
	"DB EDh,34h", "DB EDh,35h", "DB EDh,36h", "DB EDh,37h",
	"DB EDh,38h", "DB EDh,39h", "DB EDh,3Ah", "DB EDh,3Bh",
	"DB EDh,3Ch", "DB EDh,3Dh", "DB EDh,3Eh", "DB EDh,3Fh",
	"IN B,(C)", "OUT (C),B", "SBC HL,BC", "LD (#h),BC",
	"NEG", "RETN", "IM 0", "LD I,A",
	"IN C,(C)", "OUT (C),C", "ADC HL,BC", "LD BC,(#h)",
	"DB EDh,4Ch", "RETI", "DB EDh,4Eh", "LD R,A",
	"IN D,(C)", "OUT (C),D", "SBC HL,DE", "LD (#h),DE",
	"DB EDh,54h", "DB EDh,55h", "IM 1", "LD A,I",
	"IN E,(C)", "OUT (C),E", "ADC HL,DE", "LD DE,(#h)",
	"DB EDh,5Ch", "DB EDh,5Dh", "IM 2", "LD A,R",
	"IN H,(C)", "OUT (C),H", "SBC HL,HL", "LD (#h),HL",
	"DB EDh,64h", "DB EDh,65h", "DB EDh,66h", "RRD",
	"IN L,(C)", "OUT (C),L", "ADC HL,HL", "LD HL,(#h)",
	"DB EDh,6Ch", "DB EDh,6Dh", "DB EDh,6Eh", "RLD",
	"IN F,(C)", "DB EDh,71h", "SBC HL,SP", "LD (#h),SP",
	"DB EDh,74h", "DB EDh,75h", "DB EDh,76h", "DB EDh,77h",
	"IN A,(C)", "OUT (C),A", "ADC HL,SP", "LD SP,(#h)",
	"DB EDh,7Ch", "DB EDh,7Dh", "DB EDh,7Eh", "DB EDh,7Fh",
	"DB EDh,80h", "DB EDh,81h", "DB EDh,82h", "DB EDh,83h",
	"DB EDh,84h", "DB EDh,85h", "DB EDh,86h", "DB EDh,87h",
	"DB EDh,88h", "DB EDh,89h", "DB EDh,8Ah", "DB EDh,8Bh",
	"DB EDh,8Ch", "DB EDh,8Dh", "DB EDh,8Eh", "DB EDh,8Fh",
	"DB EDh,90h", "DB EDh,91h", "DB EDh,92h", "DB EDh,93h",
	"DB EDh,94h", "DB EDh,95h", "DB EDh,96h", "DB EDh,97h",
	"DB EDh,98h", "DB EDh,99h", "DB EDh,9Ah", "DB EDh,9Bh",
	"DB EDh,9Ch", "DB EDh,9Dh", "DB EDh,9Eh", "DB EDh,9Fh",
	"LDI", "CPI", "INI", "OUTI",
	"DB EDh,A4h", "DB EDh,A5h", "DB EDh,A6h", "DB EDh,A7h",
	"LDD", "CPD", "IND", "OUTD",
	"DB EDh,ACh", "DB EDh,ADh", "DB EDh,AEh", "DB EDh,AFh",
	"LDIR", "CPIR", "INIR", "OTIR",
	"DB EDh,B4h", "DB EDh,B5h", "DB EDh,B6h", "DB EDh,B7h",
	"LDDR", "CPDR", "INDR", "OTDR",
	"DB EDh,BCh", "DB EDh,BDh", "DB EDh,BEh", "DB EDh,BFh",
	"DB EDh,C0h", "DB EDh,C1h", "DB EDh,C2h", "DB EDh,C3h",
	"DB EDh,C4h", "DB EDh,C5h", "DB EDh,C6h", "DB EDh,C7h",
	"DB EDh,C8h", "DB EDh,C9h", "DB EDh,CAh", "DB EDh,CBh",
	"DB EDh,CCh", "DB EDh,CDh", "DB EDh,CEh", "DB EDh,CFh",
	"DB EDh,D0h", "DB EDh,D1h", "DB EDh,D2h", "DB EDh,D3h",
	"DB EDh,D4h", "DB EDh,D5h", "DB EDh,D6h", "DB EDh,D7h",
	"DB EDh,D8h", "DB EDh,D9h", "DB EDh,DAh", "DB EDh,DBh",
	"DB EDh,DCh", "DB EDh,DDh", "DB EDh,DEh", "DB EDh,DFh",
	"DB EDh,E0h", "DB EDh,E1h", "DB EDh,E2h", "DB EDh,E3h",
	"DB EDh,E4h", "DB EDh,E5h", "DB EDh,E6h", "DB EDh,E7h",
	"DB EDh,E8h", "DB EDh,E9h", "DB EDh,EAh", "DB EDh,EBh",
	"DB EDh,ECh", "DB EDh,EDh", "DB EDh,EEh", "DB EDh,EFh",
	"DB EDh,F0h", "DB EDh,F1h", "DB EDh,F2h", "DB EDh,F3h",
	"DB EDh,F4h", "DB EDh,F5h", "DB EDh,F6h", "DB EDh,F7h",
	"DB EDh,F8h", "DB EDh,F9h", "DB EDh,FAh", "DB EDh,FBh",
	"DB EDh,FCh", "DB EDh,FDh", "DB EDh,FEh", "DB EDh,FFh"
};

static const char* MnemonicsXX[256] =
{
	"NOP", "LD BC,#h", "LD (BC),A", "INC BC", "INC B", "DEC B", "LD B,*h", "RLCA",
	"EX AF,AF'", "ADD I%,BC", "LD A,(BC)", "DEC BC", "INC C", "DEC C", "LD C,*h", "RRCA",
	"DJNZ @h", "LD DE,#h", "LD (DE),A", "INC DE", "INC D", "DEC D", "LD D,*h", "RLA",
	"JR @h", "ADD I%,DE", "LD A,(DE)", "DEC DE", "INC E", "DEC E", "LD E,*h", "RRA",
	"JR NZ,@h", "LD I%,#h", "LD (#h),I%", "INC I%", "INC I%h", "DEC I%h", "LD I%h,*h", "DAA",
	"JR Z,@h", "ADD I%,I%", "LD I%,(#h)", "DEC I%", "INC I%l", "DEC I%l", "LD I%l,*h", "CPL",
	"JR NC,@h", "LD SP,#h", "LD (#h),A", "INC SP", "INC (I%+^h)", "DEC (I%+^h)", "LD (I%+^h),*h", "SCF",
	"JR C,@h", "ADD I%,SP", "LD A,(#h)", "DEC SP", "INC A", "DEC A", "LD A,*h", "CCF",
	"LD B,B", "LD B,C", "LD B,D", "LD B,E", "LD B,I%h", "LD B,I%l", "LD B,(I%+^h)", "LD B,A",
	"LD C,B", "LD C,C", "LD C,D", "LD C,E", "LD C,I%h", "LD C,I%l", "LD C,(I%+^h)", "LD C,A",
	"LD D,B", "LD D,C", "LD D,D", "LD D,E", "LD D,I%h", "LD D,I%l", "LD D,(I%+^h)", "LD D,A",
	"LD E,B", "LD E,C", "LD E,D", "LD E,E", "LD E,I%h", "LD E,I%l", "LD E,(I%+^h)", "LD E,A",
	"LD I%h,B", "LD I%h,C", "LD I%h,D", "LD I%h,E", "LD I%h,I%h", "LD I%h,I%l", "LD H,(I%+^h)", "LD I%h,A",
	"LD I%l,B", "LD I%l,C", "LD I%l,D", "LD I%l,E", "LD I%l,I%h", "LD I%l,I%l", "LD L,(I%+^h)", "LD I%l,A",
	"LD (I%+^h),B", "LD (I%+^h),C", "LD (I%+^h),D", "LD (I%+^h),E", "LD (I%+^h),H", "LD (I%+^h),L", "HALT", "LD (I%+^h),A",
	"LD A,B", "LD A,C", "LD A,D", "LD A,E", "LD A,I%h", "LD A,I%l", "LD A,(I%+^h)", "LD A,A",
	"ADD B", "ADD C", "ADD D", "ADD E", "ADD I%h", "ADD I%l", "ADD (I%+^h)", "ADD A",
	"ADC B", "ADC C", "ADC D", "ADC E", "ADC I%h", "ADC I%l", "ADC (I%+^h)", "ADC,A",
	"SUB B", "SUB C", "SUB D", "SUB E", "SUB I%h", "SUB I%l", "SUB (I%+^h)", "SUB A",
	"SBC B", "SBC C", "SBC D", "SBC E", "SBC I%h", "SBC I%l", "SBC (I%+^h)", "SBC A",
	"AND B", "AND C", "AND D", "AND E", "AND I%h", "AND I%l", "AND (I%+^h)", "AND A",
	"XOR B", "XOR C", "XOR D", "XOR E", "XOR I%h", "XOR I%l", "XOR (I%+^h)", "XOR A",
	"OR B", "OR C", "OR D", "OR E", "OR I%h", "OR I%l", "OR (I%+^h)", "OR A",
	"CP B", "CP C", "CP D", "CP E", "CP I%h", "CP I%l", "CP (I%+^h)", "CP A",
	"RET NZ", "POP BC", "JP NZ,#h", "JP #h", "CALL NZ,#h", "PUSH BC", "ADD *h", "RST 00h",
	"RET Z", "RET", "JP Z,#h", "PFX_CB", "CALL Z,#h", "CALL #h", "ADC *h", "RST 08h",
	"RET NC", "POP DE", "JP NC,#h", "OUTA (*h)", "CALL NC,#h", "PUSH DE", "SUB *h", "RST 10h",
	"RET C", "EXX", "JP C,#h", "INA (*h)", "CALL C,#h", "PFX_DD", "SBC *h", "RST 18h",
	"RET PO", "POP I%", "JP PO,#h", "EX I%,(SP)", "CALL PO,#h", "PUSH I%", "AND *h", "RST 20h",
	"RET PE", "LD PC,I%", "JP PE,#h", "EX DE,I%", "CALL PE,#h", "PFX_ED", "XOR *h", "RST 28h",
	"RET P", "POP AF", "JP P,#h", "DI", "CALL P,#h", "PUSH AF", "OR *h", "RST 30h",
	"RET M", "LD SP,I%", "JP M,#h", "EI", "CALL M,#h", "PFX_FD", "CP *h", "RST 38h"
};

static const char* MnemonicsXCB[256] =
{
	"RLC B", "RLC C", "RLC D", "RLC E", "RLC H", "RLC L", "RLC (I%@h)", "RLC A",
	"RRC B", "RRC C", "RRC D", "RRC E", "RRC H", "RRC L", "RRC (I%@h)", "RRC A",
	"RL B", "RL C", "RL D", "RL E", "RL H", "RL L", "RL (I%@h)", "RL A",
	"RR B", "RR C", "RR D", "RR E", "RR H", "RR L", "RR (I%@h)", "RR A",
	"SLA B", "SLA C", "SLA D", "SLA E", "SLA H", "SLA L", "SLA (I%@h)", "SLA A",
	"SRA B", "SRA C", "SRA D", "SRA E", "SRA H", "SRA L", "SRA (I%@h)", "SRA A",
	"SLL B", "SLL C", "SLL D", "SLL E", "SLL H", "SLL L", "SLL (I%@h)", "SLL A",
	"SRL B", "SRL C", "SRL D", "SRL E", "SRL H", "SRL L", "SRL (I%@h)", "SRL A",
	"BIT 0,B", "BIT 0,C", "BIT 0,D", "BIT 0,E", "BIT 0,H", "BIT 0,L", "BIT 0,(I%@h)", "BIT 0,A",
	"BIT 1,B", "BIT 1,C", "BIT 1,D", "BIT 1,E", "BIT 1,H", "BIT 1,L", "BIT 1,(I%@h)", "BIT 1,A",
	"BIT 2,B", "BIT 2,C", "BIT 2,D", "BIT 2,E", "BIT 2,H", "BIT 2,L", "BIT 2,(I%@h)", "BIT 2,A",
	"BIT 3,B", "BIT 3,C", "BIT 3,D", "BIT 3,E", "BIT 3,H", "BIT 3,L", "BIT 3,(I%@h)", "BIT 3,A",
	"BIT 4,B", "BIT 4,C", "BIT 4,D", "BIT 4,E", "BIT 4,H", "BIT 4,L", "BIT 4,(I%@h)", "BIT 4,A",
	"BIT 5,B", "BIT 5,C", "BIT 5,D", "BIT 5,E", "BIT 5,H", "BIT 5,L", "BIT 5,(I%@h)", "BIT 5,A",
	"BIT 6,B", "BIT 6,C", "BIT 6,D", "BIT 6,E", "BIT 6,H", "BIT 6,L", "BIT 6,(I%@h)", "BIT 6,A",
	"BIT 7,B", "BIT 7,C", "BIT 7,D", "BIT 7,E", "BIT 7,H", "BIT 7,L", "BIT 7,(I%@h)", "BIT 7,A",
	"RES 0,B", "RES 0,C", "RES 0,D", "RES 0,E", "RES 0,H", "RES 0,L", "RES 0,(I%@h)", "RES 0,A",
	"RES 1,B", "RES 1,C", "RES 1,D", "RES 1,E", "RES 1,H", "RES 1,L", "RES 1,(I%@h)", "RES 1,A",
	"RES 2,B", "RES 2,C", "RES 2,D", "RES 2,E", "RES 2,H", "RES 2,L", "RES 2,(I%@h)", "RES 2,A",
	"RES 3,B", "RES 3,C", "RES 3,D", "RES 3,E", "RES 3,H", "RES 3,L", "RES 3,(I%@h)", "RES 3,A",
	"RES 4,B", "RES 4,C", "RES 4,D", "RES 4,E", "RES 4,H", "RES 4,L", "RES 4,(I%@h)", "RES 4,A",
	"RES 5,B", "RES 5,C", "RES 5,D", "RES 5,E", "RES 5,H", "RES 5,L", "RES 5,(I%@h)", "RES 5,A",
	"RES 6,B", "RES 6,C", "RES 6,D", "RES 6,E", "RES 6,H", "RES 6,L", "RES 6,(I%@h)", "RES 6,A",
	"RES 7,B", "RES 7,C", "RES 7,D", "RES 7,E", "RES 7,H", "RES 7,L", "RES 7,(I%@h)", "RES 7,A",
	"SET 0,B", "SET 0,C", "SET 0,D", "SET 0,E", "SET 0,H", "SET 0,L", "SET 0,(I%@h)", "SET 0,A",
	"SET 1,B", "SET 1,C", "SET 1,D", "SET 1,E", "SET 1,H", "SET 1,L", "SET 1,(I%@h)", "SET 1,A",
	"SET 2,B", "SET 2,C", "SET 2,D", "SET 2,E", "SET 2,H", "SET 2,L", "SET 2,(I%@h)", "SET 2,A",
	"SET 3,B", "SET 3,C", "SET 3,D", "SET 3,E", "SET 3,H", "SET 3,L", "SET 3,(I%@h)", "SET 3,A",
	"SET 4,B", "SET 4,C", "SET 4,D", "SET 4,E", "SET 4,H", "SET 4,L", "SET 4,(I%@h)", "SET 4,A",
	"SET 5,B", "SET 5,C", "SET 5,D", "SET 5,E", "SET 5,H", "SET 5,L", "SET 5,(I%@h)", "SET 5,A",
	"SET 6,B", "SET 6,C", "SET 6,D", "SET 6,E", "SET 6,H", "SET 6,L", "SET 6,(I%@h)", "SET 6,A",
	"SET 7,B", "SET 7,C", "SET 7,D", "SET 7,E", "SET 7,H", "SET 7,L", "SET 7,(I%@h)", "SET 7,A"
};

static const char* CPMCalls[41] =
{
	"System Reset", "Console Input", "Console Output", "Reader Input", "Punch Output", "List Output", "Direct I/O", "Get IOByte",
	"Set IOByte", "Print String", "Read Buffered", "Console Status", "Get Version", "Reset Disk", "Select Disk", "Open File",
	"Close File", "Search First", "Search Next", "Delete File", "Read Sequential", "Write Sequential", "Make File", "Rename File",
	"Get Login Vector", "Get Current Disk", "Set DMA Address", "Get Alloc", "Write Protect Disk", "Get R/O Vector", "Set File Attr", "Get Disk Params",
	"Get/Set User", "Read Random", "Write Random", "Get File Size", "Set Random Record", "Reset Drive", "N/A", "N/A", "Write Random 0 fill"
};

int32 Watch = -1;
#endif

/* Memory management    */
static uint8 GET_BYTE(uint16 a) {
	return _RamRead(a);
}

static void PUT_BYTE(uint16 a, uint8 v) {
	_RamWrite(a, v);
}

static uint16 GET_WORD(uint16 a) {
	return _RamRead(a) | (_RamRead(a + 1) << 8);
}

static void PUT_WORD(uint16 a, uint32 v) {
	_RamWrite(a, v);
	_RamWrite(++a, v >> 8);
}

#define RAM_MM(a)   GET_BYTE(a--)
#define RAM_PP(a)   GET_BYTE(a++)

#define PUT_BYTE_PP(a,v) PUT_BYTE(a++, v)
#define PUT_BYTE_MM(a,v) PUT_BYTE(a--, v)
#define MM_PUT_BYTE(a,v) PUT_BYTE(--a, v)

#define PUSH(x) do {            \
	MM_PUT_BYTE(SP, (x) >> 8);  \
	MM_PUT_BYTE(SP, x);         \
} while (0)

/*  Macros for the IN/OUT instructions INI/INIR/IND/INDR/OUTI/OTIR/OUTD/OTDR

Pre condition
temp == value of register B at entry of the instruction
acu == value of transferred byte (IN or OUT)
Post condition
F is set correctly

Use INOUTFLAGS_ZERO(x) for INIR/INDR/OTIR/OTDR where
x == (C + 1) & 0xff for INIR
x == L              for OTIR and OTDR
x == (C - 1) & 0xff for INDR
Use INOUTFLAGS_NONZERO(x) for INI/IND/OUTI/OUTD where
x == (C + 1) & 0xff for INI
x == L              for OUTI and OUTD
x == (C - 1) & 0xff for IND
*/
#define INOUTFLAGS(syxz, x)                                             \
    AF = (AF & 0xff00) | (syxz) |               /* SF, YF, XF, ZF   */  \
        ((acu & 0x80) >> 6) |                           /* NF       */  \
        ((acu + (x)) > 0xff ? (FLAG_C | FLAG_H) : 0) |  /* CF, HF   */  \
        parityTable[((acu + (x)) & 7) ^ temp]           /* PF       */

#define INOUTFLAGS_ZERO(x)      INOUTFLAGS(FLAG_Z, x)
#define INOUTFLAGS_NONZERO(x)                                           \
    INOUTFLAGS((HIGH_REGISTER(BC) & 0xa8) | ((HIGH_REGISTER(BC) == 0) << 6), x)

static inline void Z80reset(void) {
	PC = 0;
	IFF = 0;
	IR = 0;
	Status = STATUS_RUNNING;
	Debug = 0;
	Step = -1;

	#ifndef preTables
		initTables();
	#endif
}

#ifdef DEBUG
#include "debug.h"
#endif

static inline void Z80run(void) {
	uint32 temp = 0;
	uint32 acu;
	uint32 sum;
	uint32 cbits;
	uint32 op = 0;
	uint32 adr;

	/* main instruction fetch/decode loop */
	while (!Status) {	/* loop until Status != 0 */

#ifdef DEBUG
		if (z80_check_breakpoints_on_exec(PC)) {
			Debug = 1;
		}
		if (PC == Step) {
			Debug = 1;
			Step = -1;
		}
		if (Debug)
			Z80debug();
		if (Status)
			break;
#endif

	PCX = PC;
	INCR(1); /* Add one M1 cycle to refresh counter */

	/* push instruction into trace (before it is executed) */
#if defined(DEBUG) || defined(iDEBUG)
	z80_trace_push(PCX);
#endif

#ifdef iDEBUG
		iLogFile = fopen("iDump.log", "a");
		switch (RAM[PCX & 0xffff]) {
		case 0xCB: iLogTxt = MnemonicsCB[RAM[(PCX & 0xffff) + 1]]; break;
		case 0xED: iLogTxt = MnemonicsED[RAM[(PCX & 0xffff) + 1]]; break;
		case 0xDD:
		case 0xFD:
			if (RAM[PCX & 0xffff] == 0xCB) {
				iLogTxt = MnemonicsXCB[RAM[(PCX & 0xffff) + 1]]; break;
			} else {
				iLogTxt = MnemonicsXX[RAM[(PCX & 0xffff) + 1]]; break;
			}
		default: iLogTxt = Mnemonics[RAM[PCX & 0xffff]];
		}
		sprintf(iLogBuffer, "0x%04x : 0x%02x = %s\n", PCX, RAM[PCX & 0xffff], iLogTxt);
		fputs(iLogBuffer, iLogFile);
		fclose(iLogFile);
#endif

		switch (RAM_PP(PC)) {

		case 0x00:      /* NOP */
			break;

		case 0x01:      /* LD BC,nnnn */
			BC = GET_WORD(PC++);
			++PC;
			break;

		case 0x02:      /* LD (BC),A */
			PUT_BYTE(BC, HIGH_REGISTER(AF));
			break;

		case 0x03:      /* INC BC */
			++BC;
			break;

		case 0x04:      /* INC B */
			BC += 0x100;
			temp = HIGH_REGISTER(BC);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
			break;

		case 0x05:      /* DEC B */
			BC -= 0x100;
			temp = HIGH_REGISTER(BC);
			AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
			break;

		case 0x06:      /* LD B,nn */
			SET_HIGH_REGISTER(BC, RAM_PP(PC));
			break;

		case 0x07:      /* RLCA */
			AF = ((AF >> 7) & 0x0128) | ((AF << 1) & ~0x1ff) |
				(AF & 0xc4) | ((AF >> 15) & 1);
			break;

		case 0x08:      /* EX AF,AF' */
		    AF ^= AF1;
    		AF1 ^= AF;
    		AF ^= AF1;
			break;

		case 0x09:      /* ADD HL,BC */
			HL &= ADDRMASK;
			BC &= ADDRMASK;
			sum = HL + BC;
			AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ BC ^ sum) >> 8];
			HL = sum;
			break;

		case 0x0a:      /* LD A,(BC) */
			SET_HIGH_REGISTER(AF, GET_BYTE(BC));
			break;

		case 0x0b:      /* DEC BC */
			--BC;
			break;

		case 0x0c:      /* INC C */
			temp = LOW_REGISTER(BC) + 1;
			SET_LOW_REGISTER(BC, temp);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
			break;

		case 0x0d:      /* DEC C */
			temp = LOW_REGISTER(BC) - 1;
			SET_LOW_REGISTER(BC, temp);
			AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
			break;

		case 0x0e:      /* LD C,nn */
			SET_LOW_REGISTER(BC, RAM_PP(PC));
			break;

		case 0x0f:      /* RRCA */
			AF = (AF & 0xc4) | rrcaTable[HIGH_REGISTER(AF)];
			break;

		case 0x10:      /* DJNZ dd */
			if ((BC -= 0x100) & 0xff00)
				PC += (int8)GET_BYTE(PC) + 1;
			else
				++PC;
			break;

		case 0x11:      /* LD DE,nnnn */
			DE = GET_WORD(PC++);
			++PC;
			break;

		case 0x12:      /* LD (DE),A */
			PUT_BYTE(DE, HIGH_REGISTER(AF));
			break;

		case 0x13:      /* INC DE */
			++DE;
			break;

		case 0x14:      /* INC D */
			DE += 0x100;
			temp = HIGH_REGISTER(DE);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
			break;

		case 0x15:      /* DEC D */
			DE -= 0x100;
			temp = HIGH_REGISTER(DE);
			AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
			break;

		case 0x16:      /* LD D,nn */
			SET_HIGH_REGISTER(DE, RAM_PP(PC));
			break;

		case 0x17:      /* RLA */
			AF = ((AF << 8) & 0x0100) | ((AF >> 7) & 0x28) | ((AF << 1) & ~0x01ff) |
				(AF & 0xc4) | ((AF >> 15) & 1);
			break;

		case 0x18:      /* JR dd */
			PC += (int8)GET_BYTE(PC) + 1;
			break;

		case 0x19:      /* ADD HL,DE */
			HL &= ADDRMASK;
			DE &= ADDRMASK;
			sum = HL + DE;
			AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ DE ^ sum) >> 8];
			HL = sum;
			break;

		case 0x1a:      /* LD A,(DE) */
			SET_HIGH_REGISTER(AF, GET_BYTE(DE));
			break;

		case 0x1b:      /* DEC DE */
			--DE;
			break;

		case 0x1c:      /* INC E */
			temp = LOW_REGISTER(DE) + 1;
			SET_LOW_REGISTER(DE, temp);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
			break;

		case 0x1d:      /* DEC E */
			temp = LOW_REGISTER(DE) - 1;
			SET_LOW_REGISTER(DE, temp);
			AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
			break;

		case 0x1e:      /* LD E,nn */
			SET_LOW_REGISTER(DE, RAM_PP(PC));
			break;

		case 0x1f:      /* RRA */
			AF = ((AF & 1) << 15) | (AF & 0xc4) | rraTable[HIGH_REGISTER(AF)];
			break;

		case 0x20:      /* JR NZ,dd */
			if (TSTFLAG(Z))
				++PC;
			else
				PC += (int8)GET_BYTE(PC) + 1;
			break;

		case 0x21:      /* LD HL,nnnn */
			HL = GET_WORD(PC++);
			++PC;
			break;

		case 0x22:      /* LD (nnnn),HL */
			PUT_WORD(GET_WORD(PC++), HL);
			++PC;
			break;

		case 0x23:      /* INC HL */
			++HL;
			break;

		case 0x24:      /* INC H */
			HL += 0x100;
			temp = HIGH_REGISTER(HL);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
			break;

		case 0x25:      /* DEC H */
			HL -= 0x100;
			temp = HIGH_REGISTER(HL);
			AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
			break;

		case 0x26:      /* LD H,nn */
			SET_HIGH_REGISTER(HL, RAM_PP(PC));
			break;

		case 0x27:      /* DAA */
			acu = HIGH_REGISTER(AF);
			temp = LOW_DIGIT(acu);
			cbits = TSTFLAG(C);
			if (TSTFLAG(N)) {   /* last operation was a subtract */
				int hd = cbits || acu > 0x99;
				if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
					if (temp > 5)
						SETFLAG(H, 0);
					acu -= 6;
					acu &= 0xff;
				}
				if (hd)
					acu -= 0x160;   /* adjust high digit */
			} else {          /* last operation was an add */
				if (TSTFLAG(H) || (temp > 9)) { /* adjust low digit */
					SETFLAG(H, (temp > 9));
					acu += 6;
				}
				if (cbits || ((acu & 0x1f0) > 0x90))
					acu += 0x60;   /* adjust high digit */
			}
			AF = (AF & 0x12) | rrdrldTable[acu & 0xff] | ((acu >> 8) & 1) | cbits;
			break;

		case 0x28:      /* JR Z,dd */
			if (TSTFLAG(Z))
				PC += (int8)GET_BYTE(PC) + 1;
			else
				++PC;
			break;

		case 0x29:      /* ADD HL,HL */
			HL &= ADDRMASK;
			sum = HL + HL;
			AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
			HL = sum;
			break;

		case 0x2a:      /* LD HL,(nnnn) */
			HL = GET_WORD(GET_WORD(PC++));
			++PC;
			break;

		case 0x2b:      /* DEC HL */
			--HL;
			break;

		case 0x2c:      /* INC L */
			temp = LOW_REGISTER(HL) + 1;
			SET_LOW_REGISTER(HL, temp);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
			break;

		case 0x2d:      /* DEC L */
			temp = LOW_REGISTER(HL) - 1;
			SET_LOW_REGISTER(HL, temp);
			AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
			break;

		case 0x2e:      /* LD L,nn */
			SET_LOW_REGISTER(HL, RAM_PP(PC));
			break;

		case 0x2f:      /* CPL */
			AF = (~AF & ~0xff) | (AF & 0xc5) | ((~AF >> 8) & 0x28) | 0x12;
			break;

		case 0x30:      /* JR NC,dd */
			if (TSTFLAG(C))
				++PC;
			else
				PC += (int8)GET_BYTE(PC) + 1;
			break;

		case 0x31:      /* LD SP,nnnn */
			SP = GET_WORD(PC++);
			++PC;
			break;

		case 0x32:      /* LD (nnnn),A */
			PUT_BYTE(GET_WORD(PC++), HIGH_REGISTER(AF));
			++PC;
			break;

		case 0x33:      /* INC SP */
			++SP;
			break;

		case 0x34:      /* INC (HL) */
			temp = GET_BYTE(HL) + 1;
			PUT_BYTE(HL, temp);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80);
			break;

		case 0x35:      /* DEC (HL) */
			temp = GET_BYTE(HL) - 1;
			PUT_BYTE(HL, temp);
			AF = (AF & ~0xfe) | decTable[temp & 0xff] | SET_PV2(0x7f);
			break;

		case 0x36:      /* LD (HL),nn */
			PUT_BYTE(HL, RAM_PP(PC));
			break;

		case 0x37:      /* SCF */
			AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | 1;
			break;

		case 0x38:      /* JR C,dd */
			if (TSTFLAG(C))
				PC += (int8)GET_BYTE(PC) + 1;
			else
				++PC;
			break;

		case 0x39:      /* ADD HL,SP */
			HL &= ADDRMASK;
			SP &= ADDRMASK;
			sum = HL + SP;
			AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(HL ^ SP ^ sum) >> 8];
			HL = sum;
			break;

		case 0x3a:      /* LD A,(nnnn) */
			SET_HIGH_REGISTER(AF, GET_BYTE(GET_WORD(PC++)));
			++PC;
			break;

		case 0x3b:      /* DEC SP */
			--SP;
			break;

		case 0x3c:      /* INC A */
			AF += 0x100;
			temp = HIGH_REGISTER(AF);
			AF = (AF & ~0xfe) | incTable[temp] | SET_PV2(0x80); /* SET_PV2 uses temp */
			break;

		case 0x3d:      /* DEC A */
			AF -= 0x100;
			temp = HIGH_REGISTER(AF);
			AF = (AF & ~0xfe) | decTable[temp] | SET_PV2(0x7f); /* SET_PV2 uses temp */
			break;

		case 0x3e:      /* LD A,nn */
			SET_HIGH_REGISTER(AF, RAM_PP(PC));
			break;

		case 0x3f:      /* CCF */
			AF = (AF & ~0x3b) | ((AF >> 8) & 0x28) | ((AF & 1) << 4) | (~AF & 1);
			break;

		case 0x40:      /* LD B,B */
			break;

		case 0x41:      /* LD B,C */
			BC = (BC & 0xff) | ((BC & 0xff) << 8);
			break;

		case 0x42:      /* LD B,D */
			BC = (BC & 0xff) | (DE & ~0xff);
			break;

		case 0x43:      /* LD B,E */
			BC = (BC & 0xff) | ((DE & 0xff) << 8);
			break;

		case 0x44:      /* LD B,H */
			BC = (BC & 0xff) | (HL & ~0xff);
			break;

		case 0x45:      /* LD B,L */
			BC = (BC & 0xff) | ((HL & 0xff) << 8);
			break;

		case 0x46:      /* LD B,(HL) */
			SET_HIGH_REGISTER(BC, GET_BYTE(HL));
			break;

		case 0x47:      /* LD B,A */
			BC = (BC & 0xff) | (AF & ~0xff);
			break;

		case 0x48:      /* LD C,B */
			BC = (BC & ~0xff) | ((BC >> 8) & 0xff);
			break;

		case 0x49:      /* LD C,C */
			break;

		case 0x4a:      /* LD C,D */
			BC = (BC & ~0xff) | ((DE >> 8) & 0xff);
			break;

		case 0x4b:      /* LD C,E */
			BC = (BC & ~0xff) | (DE & 0xff);
			break;

		case 0x4c:      /* LD C,H */
			BC = (BC & ~0xff) | ((HL >> 8) & 0xff);
			break;

		case 0x4d:      /* LD C,L */
			BC = (BC & ~0xff) | (HL & 0xff);
			break;

		case 0x4e:      /* LD C,(HL) */
			SET_LOW_REGISTER(BC, GET_BYTE(HL));
			break;

		case 0x4f:      /* LD C,A */
			BC = (BC & ~0xff) | ((AF >> 8) & 0xff);
			break;

		case 0x50:      /* LD D,B */
			DE = (DE & 0xff) | (BC & ~0xff);
			break;

		case 0x51:      /* LD D,C */
			DE = (DE & 0xff) | ((BC & 0xff) << 8);
			break;

		case 0x52:      /* LD D,D */
			break;

		case 0x53:      /* LD D,E */
			DE = (DE & 0xff) | ((DE & 0xff) << 8);
			break;

		case 0x54:      /* LD D,H */
			DE = (DE & 0xff) | (HL & ~0xff);
			break;

		case 0x55:      /* LD D,L */
			DE = (DE & 0xff) | ((HL & 0xff) << 8);
			break;

		case 0x56:      /* LD D,(HL) */
			SET_HIGH_REGISTER(DE, GET_BYTE(HL));
			break;

		case 0x57:      /* LD D,A */
			DE = (DE & 0xff) | (AF & ~0xff);
			break;

		case 0x58:      /* LD E,B */
			DE = (DE & ~0xff) | ((BC >> 8) & 0xff);
			break;

		case 0x59:      /* LD E,C */
			DE = (DE & ~0xff) | (BC & 0xff);
			break;

		case 0x5a:      /* LD E,D */
			DE = (DE & ~0xff) | ((DE >> 8) & 0xff);
			break;

		case 0x5b:      /* LD E,E */
			break;

		case 0x5c:      /* LD E,H */
			DE = (DE & ~0xff) | ((HL >> 8) & 0xff);
			break;

		case 0x5d:      /* LD E,L */
			DE = (DE & ~0xff) | (HL & 0xff);
			break;

		case 0x5e:      /* LD E,(HL) */
			SET_LOW_REGISTER(DE, GET_BYTE(HL));
			break;

		case 0x5f:      /* LD E,A */
			DE = (DE & ~0xff) | ((AF >> 8) & 0xff);
			break;

		case 0x60:      /* LD H,B */
			HL = (HL & 0xff) | (BC & ~0xff);
			break;

		case 0x61:      /* LD H,C */
			HL = (HL & 0xff) | ((BC & 0xff) << 8);
			break;

		case 0x62:      /* LD H,D */
			HL = (HL & 0xff) | (DE & ~0xff);
			break;

		case 0x63:      /* LD H,E */
			HL = (HL & 0xff) | ((DE & 0xff) << 8);
			break;

		case 0x64:      /* LD H,H */
			break;

		case 0x65:      /* LD H,L */
			HL = (HL & 0xff) | ((HL & 0xff) << 8);
			break;

		case 0x66:      /* LD H,(HL) */
			SET_HIGH_REGISTER(HL, GET_BYTE(HL));
			break;

		case 0x67:      /* LD H,A */
			HL = (HL & 0xff) | (AF & ~0xff);
			break;

		case 0x68:      /* LD L,B */
			HL = (HL & ~0xff) | ((BC >> 8) & 0xff);
			break;

		case 0x69:      /* LD L,C */
			HL = (HL & ~0xff) | (BC & 0xff);
			break;

		case 0x6a:      /* LD L,D */
			HL = (HL & ~0xff) | ((DE >> 8) & 0xff);
			break;

		case 0x6b:      /* LD L,E */
			HL = (HL & ~0xff) | (DE & 0xff);
			break;

		case 0x6c:      /* LD L,H */
			HL = (HL & ~0xff) | ((HL >> 8) & 0xff);
			break;

		case 0x6d:      /* LD L,L */
			break;

		case 0x6e:      /* LD L,(HL) */
			SET_LOW_REGISTER(HL, GET_BYTE(HL));
			break;

		case 0x6f:      /* LD L,A */
			HL = (HL & ~0xff) | ((AF >> 8) & 0xff);
			break;

		case 0x70:      /* LD (HL),B */
			PUT_BYTE(HL, HIGH_REGISTER(BC));
			break;

		case 0x71:      /* LD (HL),C */
			PUT_BYTE(HL, LOW_REGISTER(BC));
			break;

		case 0x72:      /* LD (HL),D */
			PUT_BYTE(HL, HIGH_REGISTER(DE));
			break;

		case 0x73:      /* LD (HL),E */
			PUT_BYTE(HL, LOW_REGISTER(DE));
			break;

		case 0x74:      /* LD (HL),H */
			PUT_BYTE(HL, HIGH_REGISTER(HL));
			break;

		case 0x75:      /* LD (HL),L */
			PUT_BYTE(HL, LOW_REGISTER(HL));
			break;

		case 0x76:      /* HALT */
#ifdef DEBUG
			_puts("\r\n::CPU HALTED::\r\n");	// A halt is a good indicator of broken code
			_puts("Press any key...");
			_getcon();
	#ifdef DEBUGONHALT
			_puts("\r\n");
			Debug = 1;
			Z80debug();
	#endif
#endif
			--PC;
			Status = STATUS_EXIT;
			break;

		case 0x77:      /* LD (HL),A */
			PUT_BYTE(HL, HIGH_REGISTER(AF));
			break;

		case 0x78:      /* LD A,B */
			AF = (AF & 0xff) | (BC & ~0xff);
			break;

		case 0x79:      /* LD A,C */
			AF = (AF & 0xff) | ((BC & 0xff) << 8);
			break;

		case 0x7a:      /* LD A,D */
			AF = (AF & 0xff) | (DE & ~0xff);
			break;

		case 0x7b:      /* LD A,E */
			AF = (AF & 0xff) | ((DE & 0xff) << 8);
			break;

		case 0x7c:      /* LD A,H */
			AF = (AF & 0xff) | (HL & ~0xff);
			break;

		case 0x7d:      /* LD A,L */
			AF = (AF & 0xff) | ((HL & 0xff) << 8);
			break;

		case 0x7e:      /* LD A,(HL) */
			SET_HIGH_REGISTER(AF, GET_BYTE(HL));
			break;

		case 0x7f:      /* LD A,A */
			break;

		case 0x80:      /* ADD A,B */
			temp = HIGH_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x81:      /* ADD A,C */
			temp = LOW_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x82:      /* ADD A,D */
			temp = HIGH_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x83:      /* ADD A,E */
			temp = LOW_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x84:      /* ADD A,H */
			temp = HIGH_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x85:      /* ADD A,L */
			temp = LOW_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x86:      /* ADD A,(HL) */
			temp = GET_BYTE(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x87:      /* ADD A,A */
			cbits = 2 * HIGH_REGISTER(AF);
			AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
			break;

		case 0x88:      /* ADC A,B */
			temp = HIGH_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x89:      /* ADC A,C */
			temp = LOW_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8a:      /* ADC A,D */
			temp = HIGH_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8b:      /* ADC A,E */
			temp = LOW_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8c:      /* ADC A,H */
			temp = HIGH_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8d:      /* ADC A,L */
			temp = LOW_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8e:      /* ADC A,(HL) */
			temp = GET_BYTE(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0x8f:      /* ADC A,A */
			cbits = 2 * HIGH_REGISTER(AF) + TSTFLAG(C);
			AF = cbitsDup8Table[cbits] | (SET_PVS(cbits));
			break;

		case 0x90:      /* SUB B */
			temp = HIGH_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x91:      /* SUB C */
			temp = LOW_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x92:      /* SUB D */
			temp = HIGH_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x93:      /* SUB E */
			temp = LOW_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x94:      /* SUB H */
			temp = HIGH_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x95:      /* SUB L */
			temp = LOW_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x96:      /* SUB (HL) */
			temp = GET_BYTE(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x97:      /* SUB A */
			AF = 0x42;
			break;

		case 0x98:      /* SBC A,B */
			temp = HIGH_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x99:      /* SBC A,C */
			temp = LOW_REGISTER(BC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9a:      /* SBC A,D */
			temp = HIGH_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9b:      /* SBC A,E */
			temp = LOW_REGISTER(DE);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9c:      /* SBC A,H */
			temp = HIGH_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9d:      /* SBC A,L */
			temp = LOW_REGISTER(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9e:      /* SBC A,(HL) */
			temp = GET_BYTE(HL);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0x9f:      /* SBC A,A */
			cbits = -TSTFLAG(C);
			AF = subTable[cbits & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PVS(cbits));
			break;

		case 0xa0:      /* AND B */
			AF = andTable[((AF & BC) >> 8) & 0xff];
			break;

		case 0xa1:      /* AND C */
			AF = andTable[((AF >> 8)& BC) & 0xff];
			break;

		case 0xa2:      /* AND D */
			AF = andTable[((AF & DE) >> 8) & 0xff];
			break;

		case 0xa3:      /* AND E */
			AF = andTable[((AF >> 8)& DE) & 0xff];
			break;

		case 0xa4:      /* AND H */
			AF = andTable[((AF & HL) >> 8) & 0xff];
			break;

		case 0xa5:      /* AND L */
			AF = andTable[((AF >> 8)& HL) & 0xff];
			break;

		case 0xa6:      /* AND (HL) */
			AF = andTable[((AF >> 8)& GET_BYTE(HL)) & 0xff];
			break;

		case 0xa7:      /* AND A */
			AF = andTable[(AF >> 8) & 0xff];
			break;

		case 0xa8:      /* XOR B */
			AF = xororTable[((AF ^ BC) >> 8) & 0xff];
			break;

		case 0xa9:      /* XOR C */
			AF = xororTable[((AF >> 8) ^ BC) & 0xff];
			break;

		case 0xaa:      /* XOR D */
			AF = xororTable[((AF ^ DE) >> 8) & 0xff];
			break;

		case 0xab:      /* XOR E */
			AF = xororTable[((AF >> 8) ^ DE) & 0xff];
			break;

		case 0xac:      /* XOR H */
			AF = xororTable[((AF ^ HL) >> 8) & 0xff];
			break;

		case 0xad:      /* XOR L */
			AF = xororTable[((AF >> 8) ^ HL) & 0xff];
			break;

		case 0xae:      /* XOR (HL) */
			AF = xororTable[((AF >> 8) ^ GET_BYTE(HL)) & 0xff];
			break;

		case 0xaf:      /* XOR A */
			AF = 0x44;
			break;

		case 0xb0:      /* OR B */
			AF = xororTable[((AF | BC) >> 8) & 0xff];
			break;

		case 0xb1:      /* OR C */
			AF = xororTable[((AF >> 8) | BC) & 0xff];
			break;

		case 0xb2:      /* OR D */
			AF = xororTable[((AF | DE) >> 8) & 0xff];
			break;

		case 0xb3:      /* OR E */
			AF = xororTable[((AF >> 8) | DE) & 0xff];
			break;

		case 0xb4:      /* OR H */
			AF = xororTable[((AF | HL) >> 8) & 0xff];
			break;

		case 0xb5:      /* OR L */
			AF = xororTable[((AF >> 8) | HL) & 0xff];
			break;

		case 0xb6:      /* OR (HL) */
			AF = xororTable[((AF >> 8) | GET_BYTE(HL)) & 0xff];
			break;

		case 0xb7:      /* OR A */
			AF = xororTable[(AF >> 8) & 0xff];
			break;

		case 0xb8:      /* CP B */
			temp = HIGH_REGISTER(BC);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xb9:      /* CP C */
			temp = LOW_REGISTER(BC);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xba:      /* CP D */
			temp = HIGH_REGISTER(DE);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xbb:      /* CP E */
			temp = LOW_REGISTER(DE);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xbc:      /* CP H */
			temp = HIGH_REGISTER(HL);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xbd:      /* CP L */
			temp = LOW_REGISTER(HL);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xbe:      /* CP (HL) */
			temp = GET_BYTE(HL);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xbf:      /* CP A */
			SET_LOW_REGISTER(AF, (HIGH_REGISTER(AF) & 0x28) | 0x42);
			break;

		case 0xc0:      /* RET NZ */
			if (!(TSTFLAG(Z)))
				POP(PC);
			break;

		case 0xc1:      /* POP BC */
			POP(BC);
			break;

		case 0xc2:      /* JP NZ,nnnn */
			JPC(!TSTFLAG(Z));
			break;

		case 0xc3:      /* JP nnnn */
			JPC(1);
			break;

		case 0xc4:      /* CALL NZ,nnnn */
			CALLC(!TSTFLAG(Z));
			break;

		case 0xc5:      /* PUSH BC */
			PUSH(BC);
			break;

		case 0xc6:      /* ADD A,nn */
			temp = RAM_PP(PC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp;
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0xc7:      /* RST 0 */
			PUSH(PC);
			PC = 0;
			break;

		case 0xc8:      /* RET Z */
			if (TSTFLAG(Z))
				POP(PC);
			break;

		case 0xc9:      /* RET */
			POP(PC);
			break;

		case 0xca:      /* JP Z,nnnn */
			JPC(TSTFLAG(Z));
			break;

		case 0xcb:      /* CB prefix */
			INCR(1); /* Add one M1 cycle to refresh counter */
			adr = HL;
			switch ((op = GET_BYTE(PC)) & 7) {

			case 0:
				acu = HIGH_REGISTER(BC);
				break;

			case 1:
				acu = LOW_REGISTER(BC);
				break;

			case 2:
				acu = HIGH_REGISTER(DE);
				break;

			case 3:
				acu = LOW_REGISTER(DE);
				break;

			case 4:
				acu = HIGH_REGISTER(HL);
				break;

			case 5:
				acu = LOW_REGISTER(HL);
				break;

			case 6:
				acu = GET_BYTE(adr);
				break;

			default:
				acu = HIGH_REGISTER(AF);
				break;
			}
			++PC;
			switch (op & 0xc0) {

			case 0x00:  /* shift/rotate */
				switch (op & 0x38) {

					case 0x00:/* RLC */
						temp = (acu << 1) | (acu >> 7);
						cbits = temp & 1;
						break;

					case 0x08:/* RRC */
						temp = (acu >> 1) | (acu << 7);
						cbits = temp & 0x80;
						break;

					case 0x10:/* RL */
						temp = (acu << 1) | TSTFLAG(C);
						cbits = acu & 0x80;
						break;

					case 0x18:/* RR */
						temp = (acu >> 1) | (TSTFLAG(C) << 7);
						cbits = acu & 1;
						break;

					case 0x20:/* SLA */
						temp = acu << 1;
						cbits = acu & 0x80;
						break;

					case 0x28:/* SRA */
						temp = (acu >> 1) | (acu & 0x80);
						cbits = acu & 1;
						break;

					case 0x30:/* SLIA */
						temp = (acu << 1) | 1;
						cbits = acu & 0x80;
						break;

					case 0x38:/* SRL */
						temp = acu >> 1;
						cbits = acu & 1;
						break;

					default:
						temp = acu;
						cbits = 0;
					}
					AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
				break;

			case 0x40:  /* BIT */
				if (acu & (1 << ((op >> 3) & 7)))
					AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
				else
					AF = (AF & ~0xfe) | 0x54;
				if ((op & 7) != 6)
					AF |= (acu & 0x28);
				temp = acu;
				break;

			case 0x80:  /* RES */
				temp = acu & ~(1 << ((op >> 3) & 7));
				break;

			case 0xc0:  /* SET */
				temp = acu | (1 << ((op >> 3) & 7));
				break;
			}
			switch (op & 7) {

			case 0:
				SET_HIGH_REGISTER(BC, temp);
				break;

			case 1:
				SET_LOW_REGISTER(BC, temp);
				break;

			case 2:
				SET_HIGH_REGISTER(DE, temp);
				break;

			case 3:
				SET_LOW_REGISTER(DE, temp);
				break;

			case 4:
				SET_HIGH_REGISTER(HL, temp);
				break;

			case 5:
				SET_LOW_REGISTER(HL, temp);
				break;

			case 6:
				PUT_BYTE(adr, temp);
				break;

			default:
				SET_HIGH_REGISTER(AF, temp);
				break;
			}
			break;

		case 0xcc:      /* CALL Z,nnnn */
			CALLC(TSTFLAG(Z));
			break;

		case 0xcd:      /* CALL nnnn */
			CALLC(1);
			break;

		case 0xce:      /* ADC A,nn */
			temp = RAM_PP(PC);
			acu = HIGH_REGISTER(AF);
			sum = acu + temp + TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = addTable[sum] | cbitsTable[cbits] | (SET_PV);
			break;

		case 0xcf:      /* RST 8 */
			PUSH(PC);
			PC = 8;
			break;

		case 0xd0:      /* RET NC */
			if (!(TSTFLAG(C)))
				POP(PC);
			break;

		case 0xd1:      /* POP DE */
			POP(DE);
			break;

		case 0xd2:      /* JP NC,nnnn */
			JPC(!TSTFLAG(C));
			break;

		case 0xd3:      /* OUT (nn),A */
			cpu_out(RAM_PP(PC), HIGH_REGISTER(AF));
			break;

		case 0xd4:      /* CALL NC,nnnn */
			CALLC(!TSTFLAG(C));
			break;

		case 0xd5:      /* PUSH DE */
			PUSH(DE);
			break;

		case 0xd6:      /* SUB nn */
			temp = RAM_PP(PC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0xd7:      /* RST 10H */
			PUSH(PC);
			PC = 0x10;
			break;

		case 0xd8:      /* RET C */
			if (TSTFLAG(C))
				POP(PC);
			break;

		case 0xd9:      /* EXX */
			BC ^= BC1;
			BC1 ^= BC;
			BC ^= BC1;
			DE ^= DE1;
			DE1 ^= DE;
			DE ^= DE1;
			HL ^= HL1;
			HL1 ^= HL;
			HL ^= HL1;
			break;

		case 0xda:      /* JP C,nnnn */
			JPC(TSTFLAG(C));
			break;

		case 0xdb:      /* IN A,(nn) */
			SET_HIGH_REGISTER(AF, cpu_in(RAM_PP(PC)));
			break;

		case 0xdc:      /* CALL C,nnnn */
			CALLC(TSTFLAG(C));
			break;

		case 0xdd:      /* DD prefix */
			INCR(1); /* Add one M1 cycle to refresh counter */
			switch (RAM_PP(PC)) {

			case 0x09:      /* ADD IX,BC */
				IX &= ADDRMASK;
				BC &= ADDRMASK;
				sum = IX + BC;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ BC ^ sum) >> 8];
				IX = sum;
				break;

			case 0x19:      /* ADD IX,DE */
				IX &= ADDRMASK;
				DE &= ADDRMASK;
				sum = IX + DE;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ DE ^ sum) >> 8];
				IX = sum;
				break;

			case 0x21:      /* LD IX,nnnn */
				IX = GET_WORD(PC++);
				++PC;
				break;

			case 0x22:      /* LD (nnnn),IX */
				PUT_WORD(GET_WORD(PC++), IX);
				++PC;
				break;

			case 0x23:      /* INC IX */
				++IX;
				break;

			case 0x24:      /* INC IXH */
				IX += 0x100;
				AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IX)];
				break;

			case 0x25:      /* DEC IXH */
				IX -= 0x100;
				AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IX)];
				break;

			case 0x26:      /* LD IXH,nn */
				SET_HIGH_REGISTER(IX, RAM_PP(PC));
				break;

			case 0x29:      /* ADD IX,IX */
				IX &= ADDRMASK;
				sum = IX + IX;
				AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
				IX = sum;
				break;

			case 0x2a:      /* LD IX,(nnnn) */
				IX = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0x2b:      /* DEC IX */
				--IX;
				break;

			case 0x2c:      /* INC IXL */
				temp = LOW_REGISTER(IX) + 1;
				SET_LOW_REGISTER(IX, temp);
				AF = (AF & ~0xfe) | incZ80Table[temp];
				break;

			case 0x2d:      /* DEC IXL */
				temp = LOW_REGISTER(IX) - 1;
				SET_LOW_REGISTER(IX, temp);
				AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
				break;

			case 0x2e:      /* LD IXL,nn */
				SET_LOW_REGISTER(IX, RAM_PP(PC));
				break;

			case 0x34:      /* INC (IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr) + 1;
				PUT_BYTE(adr, temp);
				AF = (AF & ~0xfe) | incZ80Table[temp];
				break;

			case 0x35:      /* DEC (IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr) - 1;
				PUT_BYTE(adr, temp);
				AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
				break;

			case 0x36:      /* LD (IX+dd),nn */
				adr = IX + (int8)RAM_PP(PC);
				PUT_BYTE(adr, RAM_PP(PC));
				break;

			case 0x39:      /* ADD IX,SP */
				IX &= ADDRMASK;
				SP &= ADDRMASK;
				sum = IX + SP;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IX ^ SP ^ sum) >> 8];
				IX = sum;
				break;

			case 0x44:      /* LD B,IXH */
				SET_HIGH_REGISTER(BC, HIGH_REGISTER(IX));
				break;

			case 0x45:      /* LD B,IXL */
				SET_HIGH_REGISTER(BC, LOW_REGISTER(IX));
				break;

			case 0x46:      /* LD B,(IX+dd) */
				SET_HIGH_REGISTER(BC, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x4c:      /* LD C,IXH */
				SET_LOW_REGISTER(BC, HIGH_REGISTER(IX));
				break;

			case 0x4d:      /* LD C,IXL */
				SET_LOW_REGISTER(BC, LOW_REGISTER(IX));
				break;

			case 0x4e:      /* LD C,(IX+dd) */
				SET_LOW_REGISTER(BC, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x54:      /* LD D,IXH */
				SET_HIGH_REGISTER(DE, HIGH_REGISTER(IX));
				break;

			case 0x55:      /* LD D,IXL */
				SET_HIGH_REGISTER(DE, LOW_REGISTER(IX));
				break;

			case 0x56:      /* LD D,(IX+dd) */
				SET_HIGH_REGISTER(DE, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x5c:      /* LD E,IXH */
				SET_LOW_REGISTER(DE, HIGH_REGISTER(IX));
				break;

			case 0x5d:      /* LD E,IXL */
				SET_LOW_REGISTER(DE, LOW_REGISTER(IX));
				break;

			case 0x5e:      /* LD E,(IX+dd) */
				SET_LOW_REGISTER(DE, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x60:      /* LD IXH,B */
				SET_HIGH_REGISTER(IX, HIGH_REGISTER(BC));
				break;

			case 0x61:      /* LD IXH,C */
				SET_HIGH_REGISTER(IX, LOW_REGISTER(BC));
				break;

			case 0x62:      /* LD IXH,D */
				SET_HIGH_REGISTER(IX, HIGH_REGISTER(DE));
				break;

			case 0x63:      /* LD IXH,E */
				SET_HIGH_REGISTER(IX, LOW_REGISTER(DE));
				break;

			case 0x64:      /* LD IXH,IXH */
				break;

			case 0x65:      /* LD IXH,IXL */
				SET_HIGH_REGISTER(IX, LOW_REGISTER(IX));
				break;

			case 0x66:      /* LD H,(IX+dd) */
				SET_HIGH_REGISTER(HL, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x67:      /* LD IXH,A */
				SET_HIGH_REGISTER(IX, HIGH_REGISTER(AF));
				break;

			case 0x68:      /* LD IXL,B */
				SET_LOW_REGISTER(IX, HIGH_REGISTER(BC));
				break;

			case 0x69:      /* LD IXL,C */
				SET_LOW_REGISTER(IX, LOW_REGISTER(BC));
				break;

			case 0x6a:      /* LD IXL,D */
				SET_LOW_REGISTER(IX, HIGH_REGISTER(DE));
				break;

			case 0x6b:      /* LD IXL,E */
				SET_LOW_REGISTER(IX, LOW_REGISTER(DE));
				break;

			case 0x6c:      /* LD IXL,IXH */
				SET_LOW_REGISTER(IX, HIGH_REGISTER(IX));
				break;

			case 0x6d:      /* LD IXL,IXL */
				break;

			case 0x6e:      /* LD L,(IX+dd) */
				SET_LOW_REGISTER(HL, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x6f:      /* LD IXL,A */
				SET_LOW_REGISTER(IX, HIGH_REGISTER(AF));
				break;

			case 0x70:      /* LD (IX+dd),B */
				PUT_BYTE(IX + (int8)RAM_PP(PC), HIGH_REGISTER(BC));
				break;

			case 0x71:      /* LD (IX+dd),C */
				PUT_BYTE(IX + (int8)RAM_PP(PC), LOW_REGISTER(BC));
				break;

			case 0x72:      /* LD (IX+dd),D */
				PUT_BYTE(IX + (int8)RAM_PP(PC), HIGH_REGISTER(DE));
				break;

			case 0x73:      /* LD (IX+dd),E */
				PUT_BYTE(IX + (int8)RAM_PP(PC), LOW_REGISTER(DE));
				break;

			case 0x74:      /* LD (IX+dd),H */
				PUT_BYTE(IX + (int8)RAM_PP(PC), HIGH_REGISTER(HL));
				break;

			case 0x75:      /* LD (IX+dd),L */
				PUT_BYTE(IX + (int8)RAM_PP(PC), LOW_REGISTER(HL));
				break;

			case 0x77:      /* LD (IX+dd),A */
				PUT_BYTE(IX + (int8)RAM_PP(PC), HIGH_REGISTER(AF));
				break;

			case 0x7c:      /* LD A,IXH */
				SET_HIGH_REGISTER(AF, HIGH_REGISTER(IX));
				break;

			case 0x7d:      /* LD A,IXL */
				SET_HIGH_REGISTER(AF, LOW_REGISTER(IX));
				break;

			case 0x7e:      /* LD A,(IX+dd) */
				SET_HIGH_REGISTER(AF, GET_BYTE(IX + (int8)RAM_PP(PC)));
				break;

			case 0x84:      /* ADD A,IXH */
				temp = HIGH_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x85:      /* ADD A,IXL */
				temp = LOW_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x86:      /* ADD A,(IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8c:      /* ADC A,IXH */
				temp = HIGH_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8d:      /* ADC A,IXL */
				temp = LOW_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8e:      /* ADC A,(IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x96:      /* SUB (IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x94:      /* SUB IXH */
				SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */

			case 0x9c:      /* SBC A,IXH */
				temp = HIGH_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x95:      /* SUB IXL */
				SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */

			case 0x9d:      /* SBC A,IXL */
				temp = LOW_REGISTER(IX);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x9e:      /* SBC A,(IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xa4:      /* AND IXH */
				AF = andTable[((AF & IX) >> 8) & 0xff];
				break;

			case 0xa5:      /* AND IXL */
				AF = andTable[((AF >> 8)& IX) & 0xff];
				break;

			case 0xa6:      /* AND (IX+dd) */
				AF = andTable[((AF >> 8)& GET_BYTE(IX + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xac:      /* XOR IXH */
				AF = xororTable[((AF ^ IX) >> 8) & 0xff];
				break;

			case 0xad:      /* XOR IXL */
				AF = xororTable[((AF >> 8) ^ IX) & 0xff];
				break;

			case 0xae:      /* XOR (IX+dd) */
				AF = xororTable[((AF >> 8) ^ GET_BYTE(IX + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xb4:      /* OR IXH */
				AF = xororTable[((AF | IX) >> 8) & 0xff];
				break;

			case 0xb5:      /* OR IXL */
				AF = xororTable[((AF >> 8) | IX) & 0xff];
				break;

			case 0xb6:      /* OR (IX+dd) */
				AF = xororTable[((AF >> 8) | GET_BYTE(IX + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xbc:      /* CP IXH */
				temp = HIGH_REGISTER(IX);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xbd:      /* CP IXL */
				temp = LOW_REGISTER(IX);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xbe:      /* CP (IX+dd) */
				adr = IX + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xcb:      /* CB prefix */
				adr = IX + (int8)RAM_PP(PC);
				switch ((op = GET_BYTE(PC)) & 7) {

				case 0:
					acu = HIGH_REGISTER(BC);
					break;

				case 1:
					acu = LOW_REGISTER(BC);
					break;

				case 2:
					acu = HIGH_REGISTER(DE);
					break;

				case 3:
					acu = LOW_REGISTER(DE);
					break;

				case 4:
					acu = HIGH_REGISTER(HL);
					break;

				case 5:
					acu = LOW_REGISTER(HL);
					break;

				case 6:
					acu = GET_BYTE(adr);
					break;

				default:
					acu = HIGH_REGISTER(AF);
					break;
				}
				++PC;
				switch (op & 0xc0) {

				case 0x00:  /* shift/rotate */
					switch (op & 0x38) {

						case 0x00:/* RLC */
							temp = (acu << 1) | (acu >> 7);
							cbits = temp & 1;
							break;

						case 0x08:/* RRC */
							temp = (acu >> 1) | (acu << 7);
							cbits = temp & 0x80;
							break;

						case 0x10:/* RL */
							temp = (acu << 1) | TSTFLAG(C);
							cbits = acu & 0x80;
							break;

						case 0x18:/* RR */
							temp = (acu >> 1) | (TSTFLAG(C) << 7);
							cbits = acu & 1;
							break;

						case 0x20:/* SLA */
							temp = acu << 1;
							cbits = acu & 0x80;
							break;

						case 0x28:/* SRA */
							temp = (acu >> 1) | (acu & 0x80);
							cbits = acu & 1;
							break;

						case 0x30:/* SLIA */
							temp = (acu << 1) | 1;
							cbits = acu & 0x80;
							break;

						case 0x38:/* SRL */
							temp = acu >> 1;
							cbits = acu & 1;
							break;

						default:
							temp = acu;
							cbits = 0;
					}
					AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
					break;

				case 0x40:  /* BIT */
					if (acu & (1 << ((op >> 3) & 7)))
						AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
					else
						AF = (AF & ~0xfe) | 0x54;
					if ((op & 7) != 6)
						AF |= (acu & 0x28);
					temp = acu;
					break;

				case 0x80:  /* RES */
					temp = acu & ~(1 << ((op >> 3) & 7));
					break;

				case 0xc0:  /* SET */
					temp = acu | (1 << ((op >> 3) & 7));
					break;
				}
				switch (op & 7) {

				case 0:
					SET_HIGH_REGISTER(BC, temp);
					break;

				case 1:
					SET_LOW_REGISTER(BC, temp);
					break;

				case 2:
					SET_HIGH_REGISTER(DE, temp);
					break;

				case 3:
					SET_LOW_REGISTER(DE, temp);
					break;

				case 4:
					SET_HIGH_REGISTER(HL, temp);
					break;

				case 5:
					SET_LOW_REGISTER(HL, temp);
					break;

				case 6:
					PUT_BYTE(adr, temp);
					break;

				default:
					SET_HIGH_REGISTER(AF, temp);
					break;
				}
				break;

			case 0xe1:      /* POP IX */
				POP(IX);
				break;

			case 0xe3:      /* EX (SP),IX */
				temp = IX;
				POP(IX);
				PUSH(temp);
				break;

			case 0xe5:      /* PUSH IX */
				PUSH(IX);
				break;

			case 0xe9:      /* JP (IX) */
				PC = IX;
				break;

			case 0xf9:      /* LD SP,IX */
				SP = IX;
				break;

			default:                /* ignore DD */
				--PC;
			}
			break;

		case 0xde:          /* SBC A,nn */
			temp = RAM_PP(PC);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp - TSTFLAG(C);
			cbits = acu ^ temp ^ sum;
			AF = subTable[sum & 0xff] | cbitsTable[cbits & 0x1ff] | (SET_PV);
			break;

		case 0xdf:      /* RST 18H */
			PUSH(PC);
			PC = 0x18;
			break;

		case 0xe0:      /* RET PO */
			if (!(TSTFLAG(P)))
				POP(PC);
			break;

		case 0xe1:      /* POP HL */
			POP(HL);
			break;

		case 0xe2:      /* JP PO,nnnn */
			JPC(!TSTFLAG(P));
			break;

		case 0xe3:      /* EX (SP),HL */
			temp = HL;
			POP(HL);
			PUSH(temp);
			break;

		case 0xe4:      /* CALL PO,nnnn */
			CALLC(!TSTFLAG(P));
			break;

		case 0xe5:      /* PUSH HL */
			PUSH(HL);
			break;

		case 0xe6:      /* AND nn */
			AF = andTable[((AF >> 8)& RAM_PP(PC)) & 0xff];
			break;

		case 0xe7:      /* RST 20H */
			PUSH(PC);
			PC = 0x20;
			break;

		case 0xe8:      /* RET PE */
			if (TSTFLAG(P))
				POP(PC);
			break;

		case 0xe9:      /* JP (HL) */
			PC = HL;
			break;

		case 0xea:      /* JP PE,nnnn */
			JPC(TSTFLAG(P));
			break;

		case 0xeb:      /* EX DE,HL */
			HL ^= DE;
			DE ^= HL;
			HL ^= DE;
			break;

		case 0xec:      /* CALL PE,nnnn */
			CALLC(TSTFLAG(P));
			break;

		case 0xed:      /* ED prefix */
			INCR(1); /* Add one M1 cycle to refresh counter */
			switch (RAM_PP(PC)) {

			case 0x40:      /* IN B,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_HIGH_REGISTER(BC, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x41:      /* OUT (C),B */
				cpu_out(LOW_REGISTER(BC), HIGH_REGISTER(BC));
				break;

			case 0x42:      /* SBC HL,BC */
				HL &= ADDRMASK;
				BC &= ADDRMASK;
				sum = HL - BC - TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbits2Z80Table[((HL ^ BC ^ sum) >> 8) & 0x1ff];
				HL = sum;
				break;

			case 0x43:      /* LD (nnnn),BC */
				PUT_WORD(GET_WORD(PC++), BC);
				++PC;
				break;

			case 0x44:      /* NEG */

			case 0x4C:      /* NEG, unofficial */

			case 0x54:      /* NEG, unofficial */

			case 0x5C:      /* NEG, unofficial */

			case 0x64:      /* NEG, unofficial */

			case 0x6C:      /* NEG, unofficial */

			case 0x74:      /* NEG, unofficial */

			case 0x7C:      /* NEG, unofficial */
				temp = HIGH_REGISTER(AF);
				AF = ((~(AF & 0xff00) + 1) & 0xff00); /* AF = (-(AF & 0xff00) & 0xff00); */
				AF |= ((AF >> 8) & 0xa8) | (((AF & 0xff00) == 0) << 6) | negTable[temp];
				break;

			case 0x45:      /* RETN */

			case 0x55:      /* RETN, unofficial */

			case 0x5D:      /* RETN, unofficial */

			case 0x65:      /* RETN, unofficial */

			case 0x6D:      /* RETN, unofficial */

			case 0x75:      /* RETN, unofficial */

			case 0x7D:      /* RETN, unofficial */
				IFF |= IFF >> 1;
				POP(PC);
				break;

			case 0x46:      /* IM 0 */
							/* interrupt mode 0 */
				break;

			case 0x47:      /* LD I,A */
				IR = (IR & 0xff) | (AF & ~0xff);
				break;

			case 0x48:      /* IN C,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_LOW_REGISTER(BC, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x49:      /* OUT (C),C */
				cpu_out(LOW_REGISTER(BC), LOW_REGISTER(BC));
				break;

			case 0x4a:      /* ADC HL,BC */
				HL &= ADDRMASK;
				BC &= ADDRMASK;
				sum = HL + BC + TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbitsZ80Table[(HL ^ BC ^ sum) >> 8];
				HL = sum;
				break;

			case 0x4b:      /* LD BC,(nnnn) */
				BC = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0x4d:      /* RETI */
				IFF |= IFF >> 1;
				POP(PC);
				break;

			case 0x4f:      /* LD R,A */
				IR = (IR & ~0xff) | ((AF >> 8) & 0xff);
				break;

			case 0x50:      /* IN D,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_HIGH_REGISTER(DE, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x51:      /* OUT (C),D */
				cpu_out(LOW_REGISTER(BC), HIGH_REGISTER(DE));
				break;

			case 0x52:      /* SBC HL,DE */
				HL &= ADDRMASK;
				DE &= ADDRMASK;
				sum = HL - DE - TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbits2Z80Table[((HL ^ DE ^ sum) >> 8) & 0x1ff];
				HL = sum;
				break;

			case 0x53:      /* LD (nnnn),DE */
				PUT_WORD(GET_WORD(PC++), DE);
				++PC;
				break;

			case 0x56:      /* IM 1 */
							/* interrupt mode 1 */
				break;

			case 0x57:      /* LD A,I */
				AF = (AF & 0x29) | (IR & ~0xff) | ((IR >> 8) & 0x80) | (((IR & ~0xff) == 0) << 6) | ((IFF & 2) << 1);
				break;

			case 0x58:      /* IN E,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_LOW_REGISTER(DE, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x59:      /* OUT (C),E */
				cpu_out(LOW_REGISTER(BC), LOW_REGISTER(DE));
				break;

			case 0x5a:      /* ADC HL,DE */
				HL &= ADDRMASK;
				DE &= ADDRMASK;
				sum = HL + DE + TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbitsZ80Table[(HL ^ DE ^ sum) >> 8];
				HL = sum;
				break;

			case 0x5b:      /* LD DE,(nnnn) */
				DE = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0x5e:      /* IM 2 */
							/* interrupt mode 2 */
				break;

			case 0x5f:      /* LD A,R */
				AF = (AF & 0x29) | ((IR & 0xff) << 8) | (IR & 0x80) |
					(((IR & 0xff) == 0) << 6) | ((IFF & 2) << 1);
				break;

			case 0x60:      /* IN H,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_HIGH_REGISTER(HL, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x61:      /* OUT (C),H */
				cpu_out(LOW_REGISTER(BC), HIGH_REGISTER(HL));
				break;

			case 0x62:      /* SBC HL,HL */
				HL &= ADDRMASK;
				sum = HL - HL - TSTFLAG(C);
				AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
					cbits2Z80DupTable[(sum >> 8) & 0x1ff];
				HL = sum;
				break;

			case 0x63:      /* LD (nnnn),HL */
				PUT_WORD(GET_WORD(PC++), HL);
				++PC;
				break;

			case 0x67:      /* RRD */
				temp = GET_BYTE(HL);
				acu = HIGH_REGISTER(AF);
				PUT_BYTE(HL, HIGH_DIGIT(temp) | (LOW_DIGIT(acu) << 4));
				AF = rrdrldTable[(acu & 0xf0) | LOW_DIGIT(temp)] | (AF & 1);
				break;

			case 0x68:      /* IN L,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_LOW_REGISTER(HL, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x69:      /* OUT (C),L */
				cpu_out(LOW_REGISTER(BC), LOW_REGISTER(HL));
				break;

			case 0x6a:      /* ADC HL,HL */
				HL &= ADDRMASK;
				sum = HL + HL + TSTFLAG(C);
				AF = (AF & ~0xff) | (((sum & ADDRMASK) == 0) << 6) |
					cbitsZ80DupTable[sum >> 8];
				HL = sum;
				break;

			case 0x6b:      /* LD HL,(nnnn) */
				HL = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0x6f:      /* RLD */
				temp = GET_BYTE(HL);
				acu = HIGH_REGISTER(AF);
				PUT_BYTE(HL, (LOW_DIGIT(temp) << 4) | LOW_DIGIT(acu));
				AF = rrdrldTable[(acu & 0xf0) | HIGH_DIGIT(temp)] | (AF & 1);
				break;

			case 0x70:      /* IN (C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_LOW_REGISTER(temp, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x71:      /* OUT (C),0 */
				cpu_out(LOW_REGISTER(BC), 0);
				break;

			case 0x72:      /* SBC HL,SP */
				HL &= ADDRMASK;
				SP &= ADDRMASK;
				sum = HL - SP - TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbits2Z80Table[((HL ^ SP ^ sum) >> 8) & 0x1ff];
				HL = sum;
				break;

			case 0x73:      /* LD (nnnn),SP */
				PUT_WORD(GET_WORD(PC++), SP);
				++PC;
				break;

			case 0x78:      /* IN A,(C) */
				temp = cpu_in(LOW_REGISTER(BC));
				SET_HIGH_REGISTER(AF, temp);
				AF = (AF & ~0xfe) | rotateShiftTable[temp & 0xff];
				break;

			case 0x79:      /* OUT (C),A */
				cpu_out(LOW_REGISTER(BC), HIGH_REGISTER(AF));
				break;

			case 0x7a:      /* ADC HL,SP */
				HL &= ADDRMASK;
				SP &= ADDRMASK;
				sum = HL + SP + TSTFLAG(C);
				AF = (AF & ~0xff) | ((sum >> 8) & 0xa8) | (((sum & ADDRMASK) == 0) << 6) |
					cbitsZ80Table[(HL ^ SP ^ sum) >> 8];
				HL = sum;
				break;

			case 0x7b:      /* LD SP,(nnnn) */
				SP = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0xa0:      /* LDI */
				acu = RAM_PP(HL);
				PUT_BYTE_PP(DE, acu);
				acu += HIGH_REGISTER(AF);
				AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
					(((--BC & ADDRMASK) != 0) << 2);
				break;

			case 0xa1:      /* CPI */
				acu = HIGH_REGISTER(AF);
				temp = RAM_PP(HL);
				sum = acu - temp;
				cbits = acu ^ temp ^ sum;
				AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
					(((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
					((sum - ((cbits >> 4) & 1)) & 8) |
					((--BC & ADDRMASK) != 0) << 2 | 2;
				if ((sum & 15) == 8 && (cbits & 16) != 0)
					AF &= ~8;
				break;

				/*  SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
				NF flag A is copy of bit 7 of the value read from or written to an I/O port.
				INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
				catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
				C - 1 if it's IND/INDR. So, first of all INI/INIR:
				HF and CF Both set if ((HL) + ((C + 1) & 255) > 255)
				PF The parity of (((HL) + ((C + 1) & 255)) & 7) xor B)                      */
			case 0xa2:      /* INI */
				acu = cpu_in(LOW_REGISTER(BC));
				PUT_BYTE(HL, acu);
				++HL;
				temp = HIGH_REGISTER(BC);
				BC -= 0x100;
				INOUTFLAGS_NONZERO((LOW_REGISTER(BC) + 1) & 0xff);
				break;

				/*  SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
				NF flag A is copy of bit 7 of the value read from or written to an I/O port.
				And now the for OUTI/OTIR/OUTD/OTDR instructions. Take state of the L
				after the increment or decrement of HL; add the value written to the I/O port
				to; call that k for now. If k > 255, then the CF and HF flags are set. The PF
				flags is set like the parity of k bitwise and'ed with 7, bitwise xor'ed with B.
				HF and CF Both set if ((HL) + L > 255)
				PF The parity of ((((HL) + L) & 7) xor B)                                       */
			case 0xa3:      /* OUTI */
				acu = GET_BYTE(HL);
				cpu_out(LOW_REGISTER(BC), acu);
				++HL;
				temp = HIGH_REGISTER(BC);
				BC -= 0x100;
				INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
				break;

			case 0xa8:      /* LDD */
				acu = RAM_MM(HL);
				PUT_BYTE_MM(DE, acu);
				acu += HIGH_REGISTER(AF);
				AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4) |
					(((--BC & ADDRMASK) != 0) << 2);
				break;

			case 0xa9:      /* CPD */
				acu = HIGH_REGISTER(AF);
				temp = RAM_MM(HL);
				sum = acu - temp;
				cbits = acu ^ temp ^ sum;
				AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
					(((sum - ((cbits & 16) >> 4)) & 2) << 4) | (cbits & 16) |
					((sum - ((cbits >> 4) & 1)) & 8) |
					((--BC & ADDRMASK) != 0) << 2 | 2;
				if ((sum & 15) == 8 && (cbits & 16) != 0)
					AF &= ~8;
				break;

				/*  SF, ZF, YF, XF flags are affected by decreasing register B, as in DEC B.
				NF flag A is copy of bit 7 of the value read from or written to an I/O port.
				INI/INIR/IND/INDR use the C flag in stead of the L register. There is a
				catch though, because not the value of C is used, but C + 1 if it's INI/INIR or
				C - 1 if it's IND/INDR. And last IND/INDR:
				HF and CF Both set if ((HL) + ((C - 1) & 255) > 255)
				PF The parity of (((HL) + ((C - 1) & 255)) & 7) xor B)                      */
			case 0xaa:      /* IND */
				acu = cpu_in(LOW_REGISTER(BC));
				PUT_BYTE(HL, acu);
				--HL;
				temp = HIGH_REGISTER(BC);
				BC -= 0x100;
				INOUTFLAGS_NONZERO((LOW_REGISTER(BC) - 1) & 0xff);
				break;

			case 0xab:      /* OUTD */
				acu = GET_BYTE(HL);
				cpu_out(LOW_REGISTER(BC), acu);
				--HL;
				temp = HIGH_REGISTER(BC);
				BC -= 0x100;
				INOUTFLAGS_NONZERO(LOW_REGISTER(HL));
				break;

			case 0xb0:      /* LDIR */
				BC &= ADDRMASK;
				if (BC == 0)
					BC = 0x10000;
				do {
					INCR(2); /* Add two M1 cycles to refresh counter */
					acu = RAM_PP(HL);
					PUT_BYTE_PP(DE, acu);
				} while (--BC);
				acu += HIGH_REGISTER(AF);
				AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
				break;

			case 0xb1:      /* CPIR */
				acu = HIGH_REGISTER(AF);
				BC &= ADDRMASK;
				if (BC == 0)
					BC = 0x10000;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					temp = RAM_PP(HL);
					op = --BC != 0;
					sum = acu - temp;
				} while (op && sum != 0);
				cbits = acu ^ temp ^ sum;
				AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
					(((sum - ((cbits & 16) >> 4)) & 2) << 4) |
					(cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
					op << 2 | 2;
				if ((sum & 15) == 8 && (cbits & 16) != 0)
					AF &= ~8;
				break;

			case 0xb2:      /* INIR */
				temp = HIGH_REGISTER(BC);
				if (temp == 0)
					temp = 0x100;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					acu = cpu_in(LOW_REGISTER(BC));
					PUT_BYTE(HL, acu);
					++HL;
				} while (--temp);
				temp = HIGH_REGISTER(BC);
				SET_HIGH_REGISTER(BC, 0);
				INOUTFLAGS_ZERO((LOW_REGISTER(BC) + 1) & 0xff);
				break;

			case 0xb3:      /* OTIR */
				temp = HIGH_REGISTER(BC);
				if (temp == 0)
					temp = 0x100;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					acu = GET_BYTE(HL);
					cpu_out(LOW_REGISTER(BC), acu);
					++HL;
				} while (--temp);
				temp = HIGH_REGISTER(BC);
				SET_HIGH_REGISTER(BC, 0);
				INOUTFLAGS_ZERO(LOW_REGISTER(HL));
				break;

			case 0xb8:      /* LDDR */
				BC &= ADDRMASK;
				if (BC == 0)
					BC = 0x10000;
				do {
					INCR(2); /* Add two M1 cycles to refresh counter */
					acu = RAM_MM(HL);
					PUT_BYTE_MM(DE, acu);
				} while (--BC);
				acu += HIGH_REGISTER(AF);
				AF = (AF & ~0x3e) | (acu & 8) | ((acu & 2) << 4);
				break;

			case 0xb9:      /* CPDR */
				acu = HIGH_REGISTER(AF);
				BC &= ADDRMASK;
				if (BC == 0)
					BC = 0x10000;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					temp = RAM_MM(HL);
					op = --BC != 0;
					sum = acu - temp;
				} while (op && sum != 0);
				cbits = acu ^ temp ^ sum;
				AF = (AF & ~0xfe) | (sum & 0x80) | (!(sum & 0xff) << 6) |
					(((sum - ((cbits & 16) >> 4)) & 2) << 4) |
					(cbits & 16) | ((sum - ((cbits >> 4) & 1)) & 8) |
					op << 2 | 2;
				if ((sum & 15) == 8 && (cbits & 16) != 0)
					AF &= ~8;
				break;

			case 0xba:      /* INDR */
				temp = HIGH_REGISTER(BC);
				if (temp == 0)
					temp = 0x100;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					acu = cpu_in(LOW_REGISTER(BC));
					PUT_BYTE(HL, acu);
					--HL;
				} while (--temp);
				temp = HIGH_REGISTER(BC);
				SET_HIGH_REGISTER(BC, 0);
				INOUTFLAGS_ZERO((LOW_REGISTER(BC) - 1) & 0xff);
				break;

			case 0xbb:      /* OTDR */
				temp = HIGH_REGISTER(BC);
				if (temp == 0)
					temp = 0x100;
				do {
					INCR(1); /* Add one M1 cycle to refresh counter */
					acu = GET_BYTE(HL);
					cpu_out(LOW_REGISTER(BC), acu);
					--HL;
				} while (--temp);
				temp = HIGH_REGISTER(BC);
				SET_HIGH_REGISTER(BC, 0);
				INOUTFLAGS_ZERO(LOW_REGISTER(HL));
				break;

			default:    /* ignore ED and following byte */
				break;
			}
			break;

		case 0xee:      /* XOR nn */
			AF = xororTable[((AF >> 8) ^ RAM_PP(PC)) & 0xff];
			break;

		case 0xef:      /* RST 28H */
			PUSH(PC);
			PC = 0x28;
			break;

		case 0xf0:      /* RET P */
			if (!(TSTFLAG(S)))
				POP(PC);
			break;

		case 0xf1:      /* POP AF */
			POP(AF);
			break;

		case 0xf2:      /* JP P,nnnn */
			JPC(!TSTFLAG(S));
			break;

		case 0xf3:      /* DI */
			IFF = 0;
			break;

		case 0xf4:      /* CALL P,nnnn */
			CALLC(!TSTFLAG(S));
			break;

		case 0xf5:      /* PUSH AF */
			PUSH(AF);
			break;

		case 0xf6:      /* OR nn */
			AF = xororTable[((AF >> 8) | RAM_PP(PC)) & 0xff];
			break;

		case 0xf7:      /* RST 30H */
			PUSH(PC);
			PC = 0x30;
			break;

		case 0xf8:      /* RET M */
			if (TSTFLAG(S))
				POP(PC);
			break;

		case 0xf9:      /* LD SP,HL */
			SP = HL;
			break;

		case 0xfa:      /* JP M,nnnn */
			JPC(TSTFLAG(S));
			break;

		case 0xfb:      /* EI */
			IFF = 3;
			break;

		case 0xfc:      /* CALL M,nnnn */
			CALLC(TSTFLAG(S));
			break;

		case 0xfd:      /* FD prefix */
			INCR(1); /* Add one M1 cycle to refresh counter */
			switch (RAM_PP(PC)) {

			case 0x09:      /* ADD IY,BC */
				IY &= ADDRMASK;
				BC &= ADDRMASK;
				sum = IY + BC;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ BC ^ sum) >> 8];
				IY = sum;
				break;

			case 0x19:      /* ADD IY,DE */
				IY &= ADDRMASK;
				DE &= ADDRMASK;
				sum = IY + DE;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ DE ^ sum) >> 8];
				IY = sum;
				break;

			case 0x21:      /* LD IY,nnnn */
				IY = GET_WORD(PC++);
				++PC;
				break;

			case 0x22:      /* LD (nnnn),IY */
				temp = GET_WORD(PC++);
				PUT_WORD(temp, IY);
				++PC;
				break;

			case 0x23:      /* INC IY */
				++IY;
				break;

			case 0x24:      /* INC IYH */
				IY += 0x100;
				AF = (AF & ~0xfe) | incZ80Table[HIGH_REGISTER(IY)];
				break;

			case 0x25:      /* DEC IYH */
				IY -= 0x100;
				AF = (AF & ~0xfe) | decZ80Table[HIGH_REGISTER(IY)];
				break;

			case 0x26:      /* LD IYH,nn */
				SET_HIGH_REGISTER(IY, RAM_PP(PC));
				break;

			case 0x29:      /* ADD IY,IY */
				IY &= ADDRMASK;
				sum = IY + IY;
				AF = (AF & ~0x3b) | cbitsDup16Table[sum >> 8];
				IY = sum;
				break;

			case 0x2a:      /* LD IY,(nnnn) */
				IY = GET_WORD(GET_WORD(PC++));
				++PC;
				break;

			case 0x2b:      /* DEC IY */
				--IY;
				break;

			case 0x2c:      /* INC IYL */
				temp = LOW_REGISTER(IY) + 1;
				SET_LOW_REGISTER(IY, temp);
				AF = (AF & ~0xfe) | incZ80Table[temp];
				break;

			case 0x2d:      /* DEC IYL */
				temp = LOW_REGISTER(IY) - 1;
				SET_LOW_REGISTER(IY, temp);
				AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
				break;

			case 0x2e:      /* LD IYL,nn */
				SET_LOW_REGISTER(IY, RAM_PP(PC));
				break;

			case 0x34:      /* INC (IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr) + 1;
				PUT_BYTE(adr, temp);
				AF = (AF & ~0xfe) | incZ80Table[temp];
				break;

			case 0x35:      /* DEC (IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr) - 1;
				PUT_BYTE(adr, temp);
				AF = (AF & ~0xfe) | decZ80Table[temp & 0xff];
				break;

			case 0x36:      /* LD (IY+dd),nn */
				adr = IY + (int8)RAM_PP(PC);
				PUT_BYTE(adr, RAM_PP(PC));
				break;

			case 0x39:      /* ADD IY,SP */
				IY &= ADDRMASK;
				SP &= ADDRMASK;
				sum = IY + SP;
				AF = (AF & ~0x3b) | ((sum >> 8) & 0x28) | cbitsTable[(IY ^ SP ^ sum) >> 8];
				IY = sum;
				break;

			case 0x44:      /* LD B,IYH */
				SET_HIGH_REGISTER(BC, HIGH_REGISTER(IY));
				break;

			case 0x45:      /* LD B,IYL */
				SET_HIGH_REGISTER(BC, LOW_REGISTER(IY));
				break;

			case 0x46:      /* LD B,(IY+dd) */
				SET_HIGH_REGISTER(BC, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x4c:      /* LD C,IYH */
				SET_LOW_REGISTER(BC, HIGH_REGISTER(IY));
				break;

			case 0x4d:      /* LD C,IYL */
				SET_LOW_REGISTER(BC, LOW_REGISTER(IY));
				break;

			case 0x4e:      /* LD C,(IY+dd) */
				SET_LOW_REGISTER(BC, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x54:      /* LD D,IYH */
				SET_HIGH_REGISTER(DE, HIGH_REGISTER(IY));
				break;

			case 0x55:      /* LD D,IYL */
				SET_HIGH_REGISTER(DE, LOW_REGISTER(IY));
				break;

			case 0x56:      /* LD D,(IY+dd) */
				SET_HIGH_REGISTER(DE, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x5c:      /* LD E,IYH */
				SET_LOW_REGISTER(DE, HIGH_REGISTER(IY));
				break;

			case 0x5d:      /* LD E,IYL */
				SET_LOW_REGISTER(DE, LOW_REGISTER(IY));
				break;

			case 0x5e:      /* LD E,(IY+dd) */
				SET_LOW_REGISTER(DE, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x60:      /* LD IYH,B */
				SET_HIGH_REGISTER(IY, HIGH_REGISTER(BC));
				break;

			case 0x61:      /* LD IYH,C */
				SET_HIGH_REGISTER(IY, LOW_REGISTER(BC));
				break;

			case 0x62:      /* LD IYH,D */
				SET_HIGH_REGISTER(IY, HIGH_REGISTER(DE));
				break;

			case 0x63:      /* LD IYH,E */
				SET_HIGH_REGISTER(IY, LOW_REGISTER(DE));
				break;

			case 0x64:      /* LD IYH,IYH */
				break;

			case 0x65:      /* LD IYH,IYL */
				SET_HIGH_REGISTER(IY, LOW_REGISTER(IY));
				break;

			case 0x66:      /* LD H,(IY+dd) */
				SET_HIGH_REGISTER(HL, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x67:      /* LD IYH,A */
				SET_HIGH_REGISTER(IY, HIGH_REGISTER(AF));
				break;

			case 0x68:      /* LD IYL,B */
				SET_LOW_REGISTER(IY, HIGH_REGISTER(BC));
				break;

			case 0x69:      /* LD IYL,C */
				SET_LOW_REGISTER(IY, LOW_REGISTER(BC));
				break;

			case 0x6a:      /* LD IYL,D */
				SET_LOW_REGISTER(IY, HIGH_REGISTER(DE));
				break;

			case 0x6b:      /* LD IYL,E */
				SET_LOW_REGISTER(IY, LOW_REGISTER(DE));
				break;

			case 0x6c:      /* LD IYL,IYH */
				SET_LOW_REGISTER(IY, HIGH_REGISTER(IY));
				break;

			case 0x6d:      /* LD IYL,IYL */
				break;

			case 0x6e:      /* LD L,(IY+dd) */
				SET_LOW_REGISTER(HL, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x6f:      /* LD IYL,A */
				SET_LOW_REGISTER(IY, HIGH_REGISTER(AF));
				break;

			case 0x70:      /* LD (IY+dd),B */
				PUT_BYTE(IY + (int8)RAM_PP(PC), HIGH_REGISTER(BC));
				break;

			case 0x71:      /* LD (IY+dd),C */
				PUT_BYTE(IY + (int8)RAM_PP(PC), LOW_REGISTER(BC));
				break;

			case 0x72:      /* LD (IY+dd),D */
				PUT_BYTE(IY + (int8)RAM_PP(PC), HIGH_REGISTER(DE));
				break;

			case 0x73:      /* LD (IY+dd),E */
				PUT_BYTE(IY + (int8)RAM_PP(PC), LOW_REGISTER(DE));
				break;

			case 0x74:      /* LD (IY+dd),H */
				PUT_BYTE(IY + (int8)RAM_PP(PC), HIGH_REGISTER(HL));
				break;

			case 0x75:      /* LD (IY+dd),L */
				PUT_BYTE(IY + (int8)RAM_PP(PC), LOW_REGISTER(HL));
				break;

			case 0x77:      /* LD (IY+dd),A */
				PUT_BYTE(IY + (int8)RAM_PP(PC), HIGH_REGISTER(AF));
				break;

			case 0x7c:      /* LD A,IYH */
				SET_HIGH_REGISTER(AF, HIGH_REGISTER(IY));
				break;

			case 0x7d:      /* LD A,IYL */
				SET_HIGH_REGISTER(AF, LOW_REGISTER(IY));
				break;

			case 0x7e:      /* LD A,(IY+dd) */
				SET_HIGH_REGISTER(AF, GET_BYTE(IY + (int8)RAM_PP(PC)));
				break;

			case 0x84:      /* ADD A,IYH */
				temp = HIGH_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x85:      /* ADD A,IYL */
				temp = LOW_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x86:      /* ADD A,(IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp;
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8c:      /* ADC A,IYH */
				temp = HIGH_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8d:      /* ADC A,IYL */
				temp = LOW_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x8e:      /* ADC A,(IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu + temp + TSTFLAG(C);
				AF = addTable[sum] | cbitsZ80Table[acu ^ temp ^ sum];
				break;

			case 0x96:      /* SUB (IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x94:      /* SUB IYH */
				SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */

			case 0x9c:      /* SBC A,IYH */
				temp = HIGH_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x95:      /* SUB IYL */
				SETFLAG(C, 0);/* fall through, a bit less efficient but smaller code */

			case 0x9d:      /* SBC A,IYL */
				temp = LOW_REGISTER(IY);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0x9e:      /* SBC A,(IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp - TSTFLAG(C);
				AF = addTable[sum & 0xff] | cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xa4:      /* AND IYH */
				AF = andTable[((AF & IY) >> 8) & 0xff];
				break;

			case 0xa5:      /* AND IYL */
				AF = andTable[((AF >> 8)& IY) & 0xff];
				break;

			case 0xa6:      /* AND (IY+dd) */
				AF = andTable[((AF >> 8)& GET_BYTE(IY + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xac:      /* XOR IYH */
				AF = xororTable[((AF ^ IY) >> 8) & 0xff];
				break;

			case 0xad:      /* XOR IYL */
				AF = xororTable[((AF >> 8) ^ IY) & 0xff];
				break;

			case 0xae:      /* XOR (IY+dd) */
				AF = xororTable[((AF >> 8) ^ GET_BYTE(IY + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xb4:      /* OR IYH */
				AF = xororTable[((AF | IY) >> 8) & 0xff];
				break;

			case 0xb5:      /* OR IYL */
				AF = xororTable[((AF >> 8) | IY) & 0xff];
				break;

			case 0xb6:      /* OR (IY+dd) */
				AF = xororTable[((AF >> 8) | GET_BYTE(IY + (int8)RAM_PP(PC))) & 0xff];
				break;

			case 0xbc:      /* CP IYH */
				temp = HIGH_REGISTER(IY);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xbd:      /* CP IYL */
				temp = LOW_REGISTER(IY);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xbe:      /* CP (IY+dd) */
				adr = IY + (int8)RAM_PP(PC);
				temp = GET_BYTE(adr);
				AF = (AF & ~0x28) | (temp & 0x28);
				acu = HIGH_REGISTER(AF);
				sum = acu - temp;
				AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
					cbits2Z80Table[(acu ^ temp ^ sum) & 0x1ff];
				break;

			case 0xcb:      /* CB prefix */
				adr = IY + (int8)RAM_PP(PC);
				switch ((op = GET_BYTE(PC)) & 7) {

				case 0:
					acu = HIGH_REGISTER(BC);
					break;

				case 1:
					acu = LOW_REGISTER(BC);
					break;

				case 2:
					acu = HIGH_REGISTER(DE);
					break;

				case 3:
					acu = LOW_REGISTER(DE);
					break;

				case 4:
					acu = HIGH_REGISTER(HL);
					break;

				case 5:
					acu = LOW_REGISTER(HL);
					break;

				case 6:
					acu = GET_BYTE(adr);
					break;

				default:
					acu = HIGH_REGISTER(AF);
					break;
				}
				++PC;
				switch (op & 0xc0) {

				case 0x00:  /* shift/rotate */
					switch (op & 0x38) {

						case 0x00:/* RLC */
							temp = (acu << 1) | (acu >> 7);
							cbits = temp & 1;
							break;
	
						case 0x08:/* RRC */
							temp = (acu >> 1) | (acu << 7);
							cbits = temp & 0x80;
							break;
	
						case 0x10:/* RL */
							temp = (acu << 1) | TSTFLAG(C);
							cbits = acu & 0x80;
							break;
	
						case 0x18:/* RR */
							temp = (acu >> 1) | (TSTFLAG(C) << 7);
							cbits = acu & 1;
							break;
	
						case 0x20:/* SLA */
							temp = acu << 1;
							cbits = acu & 0x80;
							break;
	
						case 0x28:/* SRA */
							temp = (acu >> 1) | (acu & 0x80);
							cbits = acu & 1;
							break;
	
						case 0x30:/* SLIA */
							temp = (acu << 1) | 1;
							cbits = acu & 0x80;
							break;
	
						case 0x38:/* SRL */
							temp = acu >> 1;
							cbits = acu & 1;
							break;
	
						default:
							temp = acu;
							cbits = 0;
					}
					AF = (AF & ~0xff) | rotateShiftTable[temp & 0xff] | !!cbits;
					break;

				case 0x40:  /* BIT */
					if (acu & (1 << ((op >> 3) & 7)))
						AF = (AF & ~0xfe) | 0x10 | (((op & 0x38) == 0x38) << 7);
					else
						AF = (AF & ~0xfe) | 0x54;
					if ((op & 7) != 6)
						AF |= (acu & 0x28);
					temp = acu;
					break;

				case 0x80:  /* RES */
					temp = acu & ~(1 << ((op >> 3) & 7));
					break;

				case 0xc0:  /* SET */
					temp = acu | (1 << ((op >> 3) & 7));
					break;
				}
				switch (op & 7) {

				case 0:
					SET_HIGH_REGISTER(BC, temp);
					break;

				case 1:
					SET_LOW_REGISTER(BC, temp);
					break;

				case 2:
					SET_HIGH_REGISTER(DE, temp);
					break;

				case 3:
					SET_LOW_REGISTER(DE, temp);
					break;

				case 4:
					SET_HIGH_REGISTER(HL, temp);
					break;

				case 5:
					SET_LOW_REGISTER(HL, temp);
					break;

				case 6:
					PUT_BYTE(adr, temp);
					break;

				default:
					SET_HIGH_REGISTER(AF, temp);
					break;
				}
				break;

			case 0xe1:      /* POP IY */
				POP(IY);
				break;

			case 0xe3:      /* EX (SP),IY */
				temp = IY;
				POP(IY);
				PUSH(temp);
				break;

			case 0xe5:      /* PUSH IY */
				PUSH(IY);
				break;

			case 0xe9:      /* JP (IY) */
				PC = IY;
				break;

			case 0xf9:      /* LD SP,IY */
				SP = IY;
				break;

			default:            /* ignore FD */
				--PC;
			}
			break;

		case 0xfe:      /* CP nn */
			temp = RAM_PP(PC);
			AF = (AF & ~0x28) | (temp & 0x28);
			acu = HIGH_REGISTER(AF);
			sum = acu - temp;
			cbits = acu ^ temp ^ sum;
			AF = (AF & ~0xff) | cpTable[sum & 0xff] | (temp & 0x28) |
				(SET_PV) | cbits2Table[cbits & 0x1ff];
			break;

		case 0xff:      /* RST 38H */
			PUSH(PC);
			PC = 0x38;
		}
	}
}


#endif
